Skip to content

Commit

Permalink
improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
zlainsama committed Mar 14, 2019
1 parent bb95856 commit 02b5141
Show file tree
Hide file tree
Showing 18 changed files with 930 additions and 598 deletions.
408 changes: 408 additions & 0 deletions src/main/java/lain/lib/Retries.java

Large diffs are not rendered by default.

213 changes: 213 additions & 0 deletions src/main/java/lain/lib/SimpleDownloader.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
package lain.lib;

import java.io.IOException;
import java.net.Proxy;
import java.net.URL;
import java.net.URLConnection;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinPool.ManagedBlocker;
import java.util.function.Consumer;
import java.util.function.Predicate;

public final class SimpleDownloader
{

private static Optional<URLConnection> connect(URL url, Proxy proxy, Consumer<URLConnection> preConnect, Consumer<Throwable> onException)
{
try
{
URLConnection conn = proxy == null ? url.openConnection() : url.openConnection(proxy);
if (preConnect != null)
preConnect.accept(conn);
conn.connect();
return Optional.of(conn);
}
catch (Throwable e)
{
if (onException != null)
onException.accept(e);
return Optional.empty();
}
}

private static boolean deleteIfExists(Path path)
{
try
{
return Files.deleteIfExists(path);
}
catch (IOException e)
{
return false;
}
}

private static Consumer<Throwable> deleteOnExceptionDecor(Path path, Consumer<Throwable> onException)
{
Consumer<Throwable> deleteOnException = e -> deleteIfExists(path);
return onException == null ? deleteOnException : deleteOnException.andThen(onException);
}

private static <T> Predicate<T> deleteOnFalseDecor(Path path, Predicate<T> predicate)
{
if (predicate == null)
return null;
return t -> {
if (predicate.test(t))
return true;
deleteIfExists(path);
return false;
};
}

private static Optional<Path> download(Path local, URLConnection conn, MessageDigest digest, Predicate<URLConnection> shouldTransfer, Consumer<Throwable> onException)
{
try
{
if (shouldTransfer != null && !shouldTransfer.test(conn))
return Optional.empty();
try (FileChannel channel = FileChannel.open(local, StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING))
{
channel.transferFrom(Channels.newChannel(digest == null ? conn.getInputStream() : new DigestInputStream(conn.getInputStream(), digest)), 0L, Long.MAX_VALUE);
return Optional.of(local);
}
}
catch (Throwable e)
{
if (digest != null)
digest.reset();
if (onException != null)
onException.accept(e);
return Optional.empty();
}
}

private static Optional<URL> resource(String resource, Consumer<Throwable> onException)
{
try
{
return Optional.of(new URL(resource));
}
catch (Throwable e)
{
if (onException != null)
onException.accept(e);
return Optional.empty();
}
}

private static void runAsync(Runnable runnable, Executor executor)
{
if (executor == null)
CompletableFuture.runAsync(runnable);
else
CompletableFuture.runAsync(runnable, executor);
}

private static void runBlocky(Runnable runnable, Consumer<Throwable> onException)
{
try
{
ForkJoinPool.managedBlock(new ManagedBlocker()
{

@Override
public boolean block() throws InterruptedException
{
runnable.run();
return true;
}

@Override
public boolean isReleasable()
{
return false;
}

});
}
catch (Throwable e)
{
if (onException != null)
onException.accept(e);
}
}

private static boolean sleep(long millis)
{
try
{
Thread.sleep(millis);
return true;
}
catch (InterruptedException e)
{
return false;
}
}

public static CompletableFuture<Optional<Path>> start(String resource)
{
return start(resource, null, null, 2, null, SharedPool::execute, null, null, null);
}

public static CompletableFuture<Optional<Path>> start(String resource, Path tempDir, Proxy proxy, int maxRetries, MessageDigest digest, Executor executor, Consumer<Thread> preExecute, Consumer<URLConnection> preConnect, Predicate<URLConnection> shouldTransfer)
{
Objects.requireNonNull(resource);
CompletableFuture<Optional<Path>> future = new CompletableFuture<>();
runAsync(() -> {
try
{
if (preExecute != null)
preExecute.accept(Thread.currentThread());
runBlocky(() -> {
resource(resource, future::completeExceptionally).ifPresent(remote -> {
Retries.retrying(() -> {
connect(remote, proxy, preConnect, Retries::rethrow).ifPresent(conn -> {
tempFile(tempDir, future::completeExceptionally).ifPresent(local -> {
download(local, conn, digest, deleteOnFalseDecor(local, shouldTransfer), deleteOnExceptionDecor(local, Retries::rethrow)).ifPresent(result -> future.complete(Optional.of(result)));
});
});
}, IOException.class::isInstance, retries -> sleep(1000L), maxRetries).toRunnable(future::completeExceptionally).run();
});
}, future::completeExceptionally);
}
finally
{
if (!future.isDone())
future.complete(Optional.empty());
}
}, executor);
return future;
}

private static Optional<Path> tempFile(Path tempDir, Consumer<Throwable> onException)
{
try
{
return Optional.of(tempDir == null ? Files.createTempFile(null, null) : Files.createTempFile(tempDir, null, null));
}
catch (Throwable e)
{
if (onException != null)
onException.accept(e);
return Optional.empty();
}
}

private SimpleDownloader()
{
}

}
24 changes: 12 additions & 12 deletions src/main/java/lain/mods/skinport/init/forge/ForgeSkinPort.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@
import lain.mods.skins.api.interfaces.ISkinProvider;
import lain.mods.skins.impl.LegacyConversion;
import lain.mods.skins.impl.SkinData;
import lain.mods.skins.providers.CrafatarCachedCapeProvider;
import lain.mods.skins.providers.CrafatarCachedSkinProvider;
import lain.mods.skins.providers.CustomServerCachedCapeProvider;
import lain.mods.skins.providers.CustomServerCachedSkinProvider;
import lain.mods.skins.providers.MojangCachedCapeProvider;
import lain.mods.skins.providers.MojangCachedSkinProvider;
import lain.mods.skins.providers.CrafatarCapeProvider;
import lain.mods.skins.providers.CrafatarSkinProvider;
import lain.mods.skins.providers.CustomServerCapeProvider;
import lain.mods.skins.providers.CustomServerSkinProvider;
import lain.mods.skins.providers.MojangCapeProvider;
import lain.mods.skins.providers.MojangSkinProvider;
import lain.mods.skins.providers.UserManagedCapeProvider;
import lain.mods.skins.providers.UserManagedSkinProvider;
import net.minecraftforge.common.MinecraftForge;
Expand Down Expand Up @@ -127,21 +127,21 @@ public void init(FMLPreInitializationEvent event)
SkinProviderAPI.SKIN.clearProviders();
SkinProviderAPI.SKIN.registerProvider(new UserManagedSkinProvider(Paths.get(".", "cachedImages")).withFilter(LegacyConversion.createFilter()));
if (useCustomServer)
SkinProviderAPI.SKIN.registerProvider(new CustomServerCachedSkinProvider(Paths.get(".", "cachedImages", "custom"), hostCustomServer).withFilter(LegacyConversion.createFilter()));
SkinProviderAPI.SKIN.registerProvider(new CustomServerSkinProvider().setHost(hostCustomServer).withFilter(LegacyConversion.createFilter()));
if (useMojang)
SkinProviderAPI.SKIN.registerProvider(new MojangCachedSkinProvider(Paths.get(".", "cachedImages", "mojang")).withFilter(LegacyConversion.createFilter()));
SkinProviderAPI.SKIN.registerProvider(new MojangSkinProvider().withFilter(LegacyConversion.createFilter()));
if (useCrafatar)
SkinProviderAPI.SKIN.registerProvider(new CrafatarCachedSkinProvider(Paths.get(".", "cachedImages", "crafatar")).withFilter(LegacyConversion.createFilter()));
SkinProviderAPI.SKIN.registerProvider(new CrafatarSkinProvider().withFilter(LegacyConversion.createFilter()));
SkinProviderAPI.SKIN.registerProvider(new DefaultSkinProvider());

SkinProviderAPI.CAPE.clearProviders();
SkinProviderAPI.CAPE.registerProvider(new UserManagedCapeProvider(Paths.get(".", "cachedImages")));
if (useCustomServer)
SkinProviderAPI.CAPE.registerProvider(new CustomServerCachedCapeProvider(Paths.get(".", "cachedImages", "custom"), hostCustomServer));
SkinProviderAPI.CAPE.registerProvider(new CustomServerCapeProvider().setHost(hostCustomServer));
if (useMojang)
SkinProviderAPI.CAPE.registerProvider(new MojangCachedCapeProvider(Paths.get(".", "cachedImages", "mojang")));
SkinProviderAPI.CAPE.registerProvider(new MojangCapeProvider());
if (useCrafatar)
SkinProviderAPI.CAPE.registerProvider(new CrafatarCachedCapeProvider(Paths.get(".", "cachedImages", "crafatar")));
SkinProviderAPI.CAPE.registerProvider(new CrafatarCapeProvider());
}

network.registerPacket(1, PacketGet0.class);
Expand Down
13 changes: 13 additions & 0 deletions src/main/java/lain/mods/skins/api/interfaces/ISkinTexture.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package lain.mods.skins.api.interfaces;

import java.nio.ByteBuffer;

public interface ISkinTexture
{

/**
* @return the ByteBuffer for this ISkinTexture. may be null.
*/
ByteBuffer getData();

}
12 changes: 6 additions & 6 deletions src/main/java/lain/mods/skins/impl/PlayerProfile.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public void onSuccess(GameProfile filled)
profile.set(filled);
}

});
}, Runnable::run);
}
}
else if (Shared.isOfflinePlayer(key.getId(), key.getName())) // an offline profile that needs resolving
Expand Down Expand Up @@ -86,10 +86,10 @@ public void onSuccess(GameProfile filled)
profile.set(filled);
}

});
}, Runnable::run);
}

});
}, Runnable::run);
}
else if (key.getProperties().isEmpty()) // an assumed online profile that needs filling
{
Expand Down Expand Up @@ -141,13 +141,13 @@ public void onSuccess(GameProfile filled)
profile.set(filled);
}

});
}, Runnable::run);
}

});
}, Runnable::run);
}

});
}, Runnable::run);
}

return profile;
Expand Down
Loading

0 comments on commit 02b5141

Please sign in to comment.