reformatted all src files (#141)
This commit is contained in:
@@ -19,349 +19,295 @@
|
||||
package appeng.services;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.util.DimensionalCoord;
|
||||
import appeng.services.compass.CompassReader;
|
||||
import appeng.services.compass.ICompassCallback;
|
||||
import appeng.util.Platform;
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
import net.minecraftforge.event.world.WorldEvent;
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||
|
||||
import appeng.api.AEApi;
|
||||
import appeng.api.util.DimensionalCoord;
|
||||
import appeng.services.compass.CompassReader;
|
||||
import appeng.services.compass.ICompassCallback;
|
||||
import appeng.util.Platform;
|
||||
import javax.annotation.Nonnull;
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.*;
|
||||
|
||||
|
||||
public final class CompassService
|
||||
{
|
||||
private static final int CHUNK_SIZE = 16;
|
||||
public final class CompassService {
|
||||
private static final int CHUNK_SIZE = 16;
|
||||
|
||||
private final Map<World, CompassReader> worldSet = new HashMap<>( 10 );
|
||||
private final ExecutorService executor;
|
||||
private final Map<World, CompassReader> worldSet = new HashMap<>(10);
|
||||
private final ExecutorService executor;
|
||||
|
||||
/**
|
||||
* AE2 Folder for each world
|
||||
*/
|
||||
private final File worldCompassFolder;
|
||||
/**
|
||||
* AE2 Folder for each world
|
||||
*/
|
||||
private final File worldCompassFolder;
|
||||
|
||||
private int jobSize;
|
||||
private int jobSize;
|
||||
|
||||
public CompassService( @Nonnull final File worldCompassFolder, @Nonnull final ThreadFactory factory )
|
||||
{
|
||||
Preconditions.checkNotNull( worldCompassFolder );
|
||||
public CompassService(@Nonnull final File worldCompassFolder, @Nonnull final ThreadFactory factory) {
|
||||
Preconditions.checkNotNull(worldCompassFolder);
|
||||
|
||||
this.worldCompassFolder = worldCompassFolder;
|
||||
this.executor = Executors.newSingleThreadExecutor( factory );
|
||||
this.jobSize = 0;
|
||||
}
|
||||
this.worldCompassFolder = worldCompassFolder;
|
||||
this.executor = Executors.newSingleThreadExecutor(factory);
|
||||
this.jobSize = 0;
|
||||
}
|
||||
|
||||
public Future<?> getCompassDirection( final DimensionalCoord coord, final int maxRange, final ICompassCallback cc )
|
||||
{
|
||||
this.jobSize++;
|
||||
return this.executor.submit( new CMDirectionRequest( coord, maxRange, cc ) );
|
||||
}
|
||||
public Future<?> getCompassDirection(final DimensionalCoord coord, final int maxRange, final ICompassCallback cc) {
|
||||
this.jobSize++;
|
||||
return this.executor.submit(new CMDirectionRequest(coord, maxRange, cc));
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure the a compass service is removed once a world gets unloaded by forge.
|
||||
*
|
||||
* @param event the event containing the unloaded world.
|
||||
*/
|
||||
@SubscribeEvent
|
||||
public void unloadWorld( final WorldEvent.Unload event )
|
||||
{
|
||||
if( Platform.isServer() && this.worldSet.containsKey( event.getWorld() ) )
|
||||
{
|
||||
final CompassReader compassReader = this.worldSet.remove( event.getWorld() );
|
||||
/**
|
||||
* Ensure the a compass service is removed once a world gets unloaded by forge.
|
||||
*
|
||||
* @param event the event containing the unloaded world.
|
||||
*/
|
||||
@SubscribeEvent
|
||||
public void unloadWorld(final WorldEvent.Unload event) {
|
||||
if (Platform.isServer() && this.worldSet.containsKey(event.getWorld())) {
|
||||
final CompassReader compassReader = this.worldSet.remove(event.getWorld());
|
||||
|
||||
compassReader.close();
|
||||
}
|
||||
}
|
||||
compassReader.close();
|
||||
}
|
||||
}
|
||||
|
||||
private int jobSize()
|
||||
{
|
||||
return this.jobSize;
|
||||
}
|
||||
private int jobSize() {
|
||||
return this.jobSize;
|
||||
}
|
||||
|
||||
private void cleanUp()
|
||||
{
|
||||
for( final CompassReader cr : this.worldSet.values() )
|
||||
{
|
||||
cr.close();
|
||||
}
|
||||
}
|
||||
private void cleanUp() {
|
||||
for (final CompassReader cr : this.worldSet.values()) {
|
||||
cr.close();
|
||||
}
|
||||
}
|
||||
|
||||
public void updateArea( final World w, final int chunkX, final int chunkZ )
|
||||
{
|
||||
final int x = chunkX << 4;
|
||||
final int z = chunkZ << 4;
|
||||
public void updateArea(final World w, final int chunkX, final int chunkZ) {
|
||||
final int x = chunkX << 4;
|
||||
final int z = chunkZ << 4;
|
||||
|
||||
this.updateArea( w, x, CHUNK_SIZE, z );
|
||||
this.updateArea( w, x, CHUNK_SIZE + 32, z );
|
||||
this.updateArea( w, x, CHUNK_SIZE + 64, z );
|
||||
this.updateArea( w, x, CHUNK_SIZE + 96, z );
|
||||
this.updateArea(w, x, CHUNK_SIZE, z);
|
||||
this.updateArea(w, x, CHUNK_SIZE + 32, z);
|
||||
this.updateArea(w, x, CHUNK_SIZE + 64, z);
|
||||
this.updateArea(w, x, CHUNK_SIZE + 96, z);
|
||||
|
||||
this.updateArea( w, x, CHUNK_SIZE + 128, z );
|
||||
this.updateArea( w, x, CHUNK_SIZE + 160, z );
|
||||
this.updateArea( w, x, CHUNK_SIZE + 192, z );
|
||||
this.updateArea( w, x, CHUNK_SIZE + 224, z );
|
||||
}
|
||||
this.updateArea(w, x, CHUNK_SIZE + 128, z);
|
||||
this.updateArea(w, x, CHUNK_SIZE + 160, z);
|
||||
this.updateArea(w, x, CHUNK_SIZE + 192, z);
|
||||
this.updateArea(w, x, CHUNK_SIZE + 224, z);
|
||||
}
|
||||
|
||||
public Future<?> updateArea( final World w, final int x, final int y, final int z )
|
||||
{
|
||||
this.jobSize++;
|
||||
public Future<?> updateArea(final World w, final int x, final int y, final int z) {
|
||||
this.jobSize++;
|
||||
|
||||
final int cx = x >> 4;
|
||||
final int cdy = y >> 5;
|
||||
final int cz = z >> 4;
|
||||
final int cx = x >> 4;
|
||||
final int cdy = y >> 5;
|
||||
final int cz = z >> 4;
|
||||
|
||||
final int low_y = cdy << 5;
|
||||
final int hi_y = low_y + 32;
|
||||
final int low_y = cdy << 5;
|
||||
final int hi_y = low_y + 32;
|
||||
|
||||
// lower level...
|
||||
final Chunk c = w.getChunkFromChunkCoords( cx, cz );
|
||||
// lower level...
|
||||
final Chunk c = w.getChunkFromChunkCoords(cx, cz);
|
||||
|
||||
Optional<Block> maybeBlock = AEApi.instance().definitions().blocks().skyStoneBlock().maybeBlock();
|
||||
if( maybeBlock.isPresent() )
|
||||
{
|
||||
Block skyStoneBlock = maybeBlock.get();
|
||||
for( int i = 0; i < CHUNK_SIZE; i++ )
|
||||
{
|
||||
for( int j = 0; j < CHUNK_SIZE; j++ )
|
||||
{
|
||||
for( int k = low_y; k < hi_y; k++ )
|
||||
{
|
||||
final Block blk = c.getBlockState( i, k, j ).getBlock();
|
||||
if( blk == skyStoneBlock )
|
||||
{
|
||||
return this.executor.submit( new CMUpdatePost( w, cx, cz, cdy, true ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Optional<Block> maybeBlock = AEApi.instance().definitions().blocks().skyStoneBlock().maybeBlock();
|
||||
if (maybeBlock.isPresent()) {
|
||||
Block skyStoneBlock = maybeBlock.get();
|
||||
for (int i = 0; i < CHUNK_SIZE; i++) {
|
||||
for (int j = 0; j < CHUNK_SIZE; j++) {
|
||||
for (int k = low_y; k < hi_y; k++) {
|
||||
final Block blk = c.getBlockState(i, k, j).getBlock();
|
||||
if (blk == skyStoneBlock) {
|
||||
return this.executor.submit(new CMUpdatePost(w, cx, cz, cdy, true));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return this.executor.submit( new CMUpdatePost( w, cx, cz, cdy, false ) );
|
||||
}
|
||||
return this.executor.submit(new CMUpdatePost(w, cx, cz, cdy, false));
|
||||
}
|
||||
|
||||
public void kill()
|
||||
{
|
||||
this.executor.shutdown();
|
||||
public void kill() {
|
||||
this.executor.shutdown();
|
||||
|
||||
try
|
||||
{
|
||||
this.executor.awaitTermination( 6, TimeUnit.MINUTES );
|
||||
this.jobSize = 0;
|
||||
try {
|
||||
this.executor.awaitTermination(6, TimeUnit.MINUTES);
|
||||
this.jobSize = 0;
|
||||
|
||||
for( final CompassReader cr : this.worldSet.values() )
|
||||
{
|
||||
cr.close();
|
||||
}
|
||||
for (final CompassReader cr : this.worldSet.values()) {
|
||||
cr.close();
|
||||
}
|
||||
|
||||
this.worldSet.clear();
|
||||
}
|
||||
catch( final InterruptedException e )
|
||||
{
|
||||
// wrap this up..
|
||||
}
|
||||
}
|
||||
this.worldSet.clear();
|
||||
} catch (final InterruptedException e) {
|
||||
// wrap this up..
|
||||
}
|
||||
}
|
||||
|
||||
private CompassReader getReader( final World w )
|
||||
{
|
||||
CompassReader cr = this.worldSet.get( w );
|
||||
private CompassReader getReader(final World w) {
|
||||
CompassReader cr = this.worldSet.get(w);
|
||||
|
||||
if( cr == null )
|
||||
{
|
||||
cr = new CompassReader( w.provider.getDimension(), this.worldCompassFolder );
|
||||
this.worldSet.put( w, cr );
|
||||
}
|
||||
if (cr == null) {
|
||||
cr = new CompassReader(w.provider.getDimension(), this.worldCompassFolder);
|
||||
this.worldSet.put(w, cr);
|
||||
}
|
||||
|
||||
return cr;
|
||||
}
|
||||
return cr;
|
||||
}
|
||||
|
||||
private int dist( final int ax, final int az, final int bx, final int bz )
|
||||
{
|
||||
final int up = ( bz - az ) * CHUNK_SIZE;
|
||||
final int side = ( bx - ax ) * CHUNK_SIZE;
|
||||
private int dist(final int ax, final int az, final int bx, final int bz) {
|
||||
final int up = (bz - az) * CHUNK_SIZE;
|
||||
final int side = (bx - ax) * CHUNK_SIZE;
|
||||
|
||||
return up * up + side * side;
|
||||
}
|
||||
return up * up + side * side;
|
||||
}
|
||||
|
||||
private double rad( final int ax, final int az, final int bx, final int bz )
|
||||
{
|
||||
final int up = bz - az;
|
||||
final int side = bx - ax;
|
||||
private double rad(final int ax, final int az, final int bx, final int bz) {
|
||||
final int up = bz - az;
|
||||
final int side = bx - ax;
|
||||
|
||||
return Math.atan2( -up, side ) - Math.PI / 2.0;
|
||||
}
|
||||
return Math.atan2(-up, side) - Math.PI / 2.0;
|
||||
}
|
||||
|
||||
private class CMUpdatePost implements Runnable
|
||||
{
|
||||
private class CMUpdatePost implements Runnable {
|
||||
|
||||
public final World world;
|
||||
public final World world;
|
||||
|
||||
public final int chunkX;
|
||||
public final int chunkZ;
|
||||
public final int doubleChunkY; // 32 blocks instead of 16.
|
||||
public final boolean value;
|
||||
public final int chunkX;
|
||||
public final int chunkZ;
|
||||
public final int doubleChunkY; // 32 blocks instead of 16.
|
||||
public final boolean value;
|
||||
|
||||
public CMUpdatePost( final World w, final int cx, final int cz, final int dcy, final boolean val )
|
||||
{
|
||||
this.world = w;
|
||||
this.chunkX = cx;
|
||||
this.doubleChunkY = dcy;
|
||||
this.chunkZ = cz;
|
||||
this.value = val;
|
||||
}
|
||||
public CMUpdatePost(final World w, final int cx, final int cz, final int dcy, final boolean val) {
|
||||
this.world = w;
|
||||
this.chunkX = cx;
|
||||
this.doubleChunkY = dcy;
|
||||
this.chunkZ = cz;
|
||||
this.value = val;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
CompassService.this.jobSize--;
|
||||
@Override
|
||||
public void run() {
|
||||
CompassService.this.jobSize--;
|
||||
|
||||
final CompassReader cr = CompassService.this.getReader( this.world );
|
||||
cr.setHasBeacon( this.chunkX, this.chunkZ, this.doubleChunkY, this.value );
|
||||
final CompassReader cr = CompassService.this.getReader(this.world);
|
||||
cr.setHasBeacon(this.chunkX, this.chunkZ, this.doubleChunkY, this.value);
|
||||
|
||||
if( CompassService.this.jobSize() < 2 )
|
||||
{
|
||||
CompassService.this.cleanUp();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (CompassService.this.jobSize() < 2) {
|
||||
CompassService.this.cleanUp();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class CMDirectionRequest implements Runnable
|
||||
{
|
||||
private class CMDirectionRequest implements Runnable {
|
||||
|
||||
public final int maxRange;
|
||||
public final DimensionalCoord coord;
|
||||
public final ICompassCallback callback;
|
||||
public final int maxRange;
|
||||
public final DimensionalCoord coord;
|
||||
public final ICompassCallback callback;
|
||||
|
||||
public CMDirectionRequest( final DimensionalCoord coord, final int getMaxRange, final ICompassCallback cc )
|
||||
{
|
||||
this.coord = coord;
|
||||
this.maxRange = getMaxRange;
|
||||
this.callback = cc;
|
||||
}
|
||||
public CMDirectionRequest(final DimensionalCoord coord, final int getMaxRange, final ICompassCallback cc) {
|
||||
this.coord = coord;
|
||||
this.maxRange = getMaxRange;
|
||||
this.callback = cc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
CompassService.this.jobSize--;
|
||||
@Override
|
||||
public void run() {
|
||||
CompassService.this.jobSize--;
|
||||
|
||||
final int cx = this.coord.x >> 4;
|
||||
final int cz = this.coord.z >> 4;
|
||||
final int cx = this.coord.x >> 4;
|
||||
final int cz = this.coord.z >> 4;
|
||||
|
||||
final CompassReader cr = CompassService.this.getReader( this.coord.getWorld() );
|
||||
final CompassReader cr = CompassService.this.getReader(this.coord.getWorld());
|
||||
|
||||
// Am I standing on it?
|
||||
if( cr.hasBeacon( cx, cz ) )
|
||||
{
|
||||
this.callback.calculatedDirection( true, true, -999, 0 );
|
||||
// Am I standing on it?
|
||||
if (cr.hasBeacon(cx, cz)) {
|
||||
this.callback.calculatedDirection(true, true, -999, 0);
|
||||
|
||||
if( CompassService.this.jobSize() < 2 )
|
||||
{
|
||||
CompassService.this.cleanUp();
|
||||
}
|
||||
if (CompassService.this.jobSize() < 2) {
|
||||
CompassService.this.cleanUp();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// spiral outward...
|
||||
for( int offset = 1; offset < this.maxRange; offset++ )
|
||||
{
|
||||
final int minX = cx - offset;
|
||||
final int minZ = cz - offset;
|
||||
final int maxX = cx + offset;
|
||||
final int maxZ = cz + offset;
|
||||
// spiral outward...
|
||||
for (int offset = 1; offset < this.maxRange; offset++) {
|
||||
final int minX = cx - offset;
|
||||
final int minZ = cz - offset;
|
||||
final int maxX = cx + offset;
|
||||
final int maxZ = cz + offset;
|
||||
|
||||
int closest = Integer.MAX_VALUE;
|
||||
int chosen_x = cx;
|
||||
int chosen_z = cz;
|
||||
int closest = Integer.MAX_VALUE;
|
||||
int chosen_x = cx;
|
||||
int chosen_z = cz;
|
||||
|
||||
for( int z = minZ; z <= maxZ; z++ )
|
||||
{
|
||||
if( cr.hasBeacon( minX, z ) )
|
||||
{
|
||||
final int closeness = CompassService.this.dist( cx, cz, minX, z );
|
||||
if( closeness < closest )
|
||||
{
|
||||
closest = closeness;
|
||||
chosen_x = minX;
|
||||
chosen_z = z;
|
||||
}
|
||||
}
|
||||
for (int z = minZ; z <= maxZ; z++) {
|
||||
if (cr.hasBeacon(minX, z)) {
|
||||
final int closeness = CompassService.this.dist(cx, cz, minX, z);
|
||||
if (closeness < closest) {
|
||||
closest = closeness;
|
||||
chosen_x = minX;
|
||||
chosen_z = z;
|
||||
}
|
||||
}
|
||||
|
||||
if( cr.hasBeacon( maxX, z ) )
|
||||
{
|
||||
final int closeness = CompassService.this.dist( cx, cz, maxX, z );
|
||||
if( closeness < closest )
|
||||
{
|
||||
closest = closeness;
|
||||
chosen_x = maxX;
|
||||
chosen_z = z;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cr.hasBeacon(maxX, z)) {
|
||||
final int closeness = CompassService.this.dist(cx, cz, maxX, z);
|
||||
if (closeness < closest) {
|
||||
closest = closeness;
|
||||
chosen_x = maxX;
|
||||
chosen_z = z;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for( int x = minX + 1; x < maxX; x++ )
|
||||
{
|
||||
if( cr.hasBeacon( x, minZ ) )
|
||||
{
|
||||
final int closeness = CompassService.this.dist( cx, cz, x, minZ );
|
||||
if( closeness < closest )
|
||||
{
|
||||
closest = closeness;
|
||||
chosen_x = x;
|
||||
chosen_z = minZ;
|
||||
}
|
||||
}
|
||||
for (int x = minX + 1; x < maxX; x++) {
|
||||
if (cr.hasBeacon(x, minZ)) {
|
||||
final int closeness = CompassService.this.dist(cx, cz, x, minZ);
|
||||
if (closeness < closest) {
|
||||
closest = closeness;
|
||||
chosen_x = x;
|
||||
chosen_z = minZ;
|
||||
}
|
||||
}
|
||||
|
||||
if( cr.hasBeacon( x, maxZ ) )
|
||||
{
|
||||
final int closeness = CompassService.this.dist( cx, cz, x, maxZ );
|
||||
if( closeness < closest )
|
||||
{
|
||||
closest = closeness;
|
||||
chosen_x = x;
|
||||
chosen_z = maxZ;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cr.hasBeacon(x, maxZ)) {
|
||||
final int closeness = CompassService.this.dist(cx, cz, x, maxZ);
|
||||
if (closeness < closest) {
|
||||
closest = closeness;
|
||||
chosen_x = x;
|
||||
chosen_z = maxZ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( closest < Integer.MAX_VALUE )
|
||||
{
|
||||
this.callback.calculatedDirection( true, false, CompassService.this.rad( cx, cz, chosen_x, chosen_z ),
|
||||
CompassService.this.dist( cx, cz, chosen_x, chosen_z ) );
|
||||
if (closest < Integer.MAX_VALUE) {
|
||||
this.callback.calculatedDirection(true, false, CompassService.this.rad(cx, cz, chosen_x, chosen_z),
|
||||
CompassService.this.dist(cx, cz, chosen_x, chosen_z));
|
||||
|
||||
if( CompassService.this.jobSize() < 2 )
|
||||
{
|
||||
CompassService.this.cleanUp();
|
||||
}
|
||||
if (CompassService.this.jobSize() < 2) {
|
||||
CompassService.this.cleanUp();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// didn't find shit...
|
||||
this.callback.calculatedDirection( false, true, -999, 999 );
|
||||
// didn't find shit...
|
||||
this.callback.calculatedDirection(false, true, -999, 999);
|
||||
|
||||
if( CompassService.this.jobSize() < 2 )
|
||||
{
|
||||
CompassService.this.cleanUp();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (CompassService.this.jobSize() < 2) {
|
||||
CompassService.this.cleanUp();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,186 +19,158 @@
|
||||
package appeng.services;
|
||||
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import appeng.core.AEConfig;
|
||||
import appeng.core.AELog;
|
||||
import appeng.core.AppEng;
|
||||
import appeng.services.version.*;
|
||||
import appeng.services.version.github.FormattedRelease;
|
||||
import appeng.services.version.github.ReleaseFetcher;
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraftforge.fml.common.Loader;
|
||||
import net.minecraftforge.fml.common.event.FMLInterModComms;
|
||||
|
||||
import appeng.core.AEConfig;
|
||||
import appeng.core.AELog;
|
||||
import appeng.core.AppEng;
|
||||
import appeng.services.version.ModVersionFetcher;
|
||||
import appeng.services.version.Version;
|
||||
import appeng.services.version.VersionCheckerConfig;
|
||||
import appeng.services.version.VersionFetcher;
|
||||
import appeng.services.version.VersionParser;
|
||||
import appeng.services.version.github.FormattedRelease;
|
||||
import appeng.services.version.github.ReleaseFetcher;
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.Date;
|
||||
|
||||
|
||||
/**
|
||||
* Tries to connect to GitHub to retrieve the most current build.
|
||||
* After comparison with the local version, several path can be chosen.
|
||||
*
|
||||
* <p>
|
||||
* If the local version is invalid, somebody might have build that version themselves
|
||||
* or it is run in a developer environment, then nothing needs to be done.
|
||||
*
|
||||
* <p>
|
||||
* If GitHub can not be reached, then either is GitHub down
|
||||
* or the connection to GitHub disturbed, then nothing needs to be done,
|
||||
* since no comparison can be reached
|
||||
*
|
||||
* <p>
|
||||
* If the version was just recently checked, then no need to poll again.
|
||||
* Nobody wants to bother to update several times a day.
|
||||
*
|
||||
* <p>
|
||||
* Config enables to fine-tune when a version is considered newer
|
||||
*
|
||||
* <p>
|
||||
* If the local version is newer or equal to the GitHub version,
|
||||
* then no update needs to be posted
|
||||
*
|
||||
* <p>
|
||||
* Only after all that cases, if the external version is higher than the local,
|
||||
* use Version Checker Mod and post several information needed for it to update the mod.
|
||||
*/
|
||||
public final class VersionChecker implements Runnable
|
||||
{
|
||||
private static final int SEC_TO_HOUR = 3600;
|
||||
private static final int MS_TO_SEC = 1000;
|
||||
private final VersionCheckerConfig config;
|
||||
public final class VersionChecker implements Runnable {
|
||||
private static final int SEC_TO_HOUR = 3600;
|
||||
private static final int MS_TO_SEC = 1000;
|
||||
private final VersionCheckerConfig config;
|
||||
|
||||
public VersionChecker( @Nonnull final VersionCheckerConfig config )
|
||||
{
|
||||
Preconditions.checkNotNull( config );
|
||||
public VersionChecker(@Nonnull final VersionCheckerConfig config) {
|
||||
Preconditions.checkNotNull(config);
|
||||
|
||||
this.config = config;
|
||||
}
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
try
|
||||
{
|
||||
Thread.yield();
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
Thread.yield();
|
||||
|
||||
// persist the config
|
||||
this.config.save();
|
||||
// persist the config
|
||||
this.config.save();
|
||||
|
||||
// retrieve data
|
||||
final String rawLastCheck = this.config.lastCheck();
|
||||
// retrieve data
|
||||
final String rawLastCheck = this.config.lastCheck();
|
||||
|
||||
// process data
|
||||
final long lastCheck = Long.parseLong( rawLastCheck );
|
||||
final Date now = new Date();
|
||||
final long nowInMs = now.getTime();
|
||||
final long intervalInMs = this.config.interval() * SEC_TO_HOUR * MS_TO_SEC;
|
||||
final long lastAfterInterval = lastCheck + intervalInMs;
|
||||
// process data
|
||||
final long lastCheck = Long.parseLong(rawLastCheck);
|
||||
final Date now = new Date();
|
||||
final long nowInMs = now.getTime();
|
||||
final long intervalInMs = this.config.interval() * SEC_TO_HOUR * MS_TO_SEC;
|
||||
final long lastAfterInterval = lastCheck + intervalInMs;
|
||||
|
||||
this.processInterval( nowInMs, lastAfterInterval );
|
||||
}
|
||||
catch( final Exception exception )
|
||||
{
|
||||
// Log any unhandled exception to prevent the JVM from reporting them as unhandled.
|
||||
AELog.debug( exception );
|
||||
}
|
||||
this.processInterval(nowInMs, lastAfterInterval);
|
||||
} catch (final Exception exception) {
|
||||
// Log any unhandled exception to prevent the JVM from reporting them as unhandled.
|
||||
AELog.debug(exception);
|
||||
}
|
||||
|
||||
AELog.info( "Stopping AE2 VersionChecker" );
|
||||
}
|
||||
AELog.info("Stopping AE2 VersionChecker");
|
||||
}
|
||||
|
||||
/**
|
||||
* checks if enough time since last check has expired
|
||||
*
|
||||
* @param nowInMs now in milli seconds
|
||||
* @param lastAfterInterval last version check including the interval defined in the config
|
||||
*/
|
||||
private void processInterval( final long nowInMs, final long lastAfterInterval )
|
||||
{
|
||||
if( nowInMs > lastAfterInterval )
|
||||
{
|
||||
final String rawModVersion = AEConfig.VERSION;
|
||||
final VersionParser parser = new VersionParser();
|
||||
final VersionFetcher modFetcher = new ModVersionFetcher( rawModVersion, parser );
|
||||
final ReleaseFetcher githubFetcher = new ReleaseFetcher( this.config, parser );
|
||||
/**
|
||||
* checks if enough time since last check has expired
|
||||
*
|
||||
* @param nowInMs now in milli seconds
|
||||
* @param lastAfterInterval last version check including the interval defined in the config
|
||||
*/
|
||||
private void processInterval(final long nowInMs, final long lastAfterInterval) {
|
||||
if (nowInMs > lastAfterInterval) {
|
||||
final String rawModVersion = AEConfig.VERSION;
|
||||
final VersionParser parser = new VersionParser();
|
||||
final VersionFetcher modFetcher = new ModVersionFetcher(rawModVersion, parser);
|
||||
final ReleaseFetcher githubFetcher = new ReleaseFetcher(this.config, parser);
|
||||
|
||||
final Version modVersion = modFetcher.get();
|
||||
final FormattedRelease githubRelease = githubFetcher.get();
|
||||
final Version modVersion = modFetcher.get();
|
||||
final FormattedRelease githubRelease = githubFetcher.get();
|
||||
|
||||
this.processVersions( modVersion, githubRelease );
|
||||
}
|
||||
else
|
||||
{
|
||||
AELog.info( "Last check was just recently." );
|
||||
}
|
||||
}
|
||||
this.processVersions(modVersion, githubRelease);
|
||||
} else {
|
||||
AELog.info("Last check was just recently.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the retrieved version is newer as the current mod version.
|
||||
* Will notify player if config is enabled.
|
||||
*
|
||||
* @param modVersion version of mod
|
||||
* @param githubRelease release retrieved through github
|
||||
*/
|
||||
private void processVersions( @Nonnull final Version modVersion, @Nonnull final FormattedRelease githubRelease )
|
||||
{
|
||||
final Version githubVersion = githubRelease.version();
|
||||
final String modFormatted = modVersion.formatted();
|
||||
final String ghFormatted = githubVersion.formatted();
|
||||
/**
|
||||
* Checks if the retrieved version is newer as the current mod version.
|
||||
* Will notify player if config is enabled.
|
||||
*
|
||||
* @param modVersion version of mod
|
||||
* @param githubRelease release retrieved through github
|
||||
*/
|
||||
private void processVersions(@Nonnull final Version modVersion, @Nonnull final FormattedRelease githubRelease) {
|
||||
final Version githubVersion = githubRelease.version();
|
||||
final String modFormatted = modVersion.formatted();
|
||||
final String ghFormatted = githubVersion.formatted();
|
||||
|
||||
if( githubVersion.isNewerAs( modVersion ) )
|
||||
{
|
||||
final String changelog = githubRelease.changelog();
|
||||
if (githubVersion.isNewerAs(modVersion)) {
|
||||
final String changelog = githubRelease.changelog();
|
||||
|
||||
if( this.config.shouldNotifyPlayer() )
|
||||
{
|
||||
AELog.info( "Newer version is available: " + ghFormatted + " (found) > " + modFormatted + " (current)" );
|
||||
if (this.config.shouldNotifyPlayer()) {
|
||||
AELog.info("Newer version is available: " + ghFormatted + " (found) > " + modFormatted + " (current)");
|
||||
|
||||
if( this.config.shouldPostChangelog() )
|
||||
{
|
||||
AELog.info( "Changelog: " + changelog );
|
||||
}
|
||||
}
|
||||
if (this.config.shouldPostChangelog()) {
|
||||
AELog.info("Changelog: " + changelog);
|
||||
}
|
||||
}
|
||||
|
||||
this.interactWithVersionCheckerMod( modFormatted, ghFormatted, changelog );
|
||||
}
|
||||
else
|
||||
{
|
||||
AELog.info( "No newer version is available: " + ghFormatted + "(found) < " + modFormatted + " (current)" );
|
||||
}
|
||||
}
|
||||
this.interactWithVersionCheckerMod(modFormatted, ghFormatted, changelog);
|
||||
} else {
|
||||
AELog.info("No newer version is available: " + ghFormatted + "(found) < " + modFormatted + " (current)");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the version checker mod is installed and handles it depending on that information
|
||||
*
|
||||
* @param modFormatted mod version formatted as rv2-beta-8
|
||||
* @param ghFormatted retrieved github version formatted as rv2-beta-8
|
||||
* @param changelog retrieved github changelog
|
||||
*/
|
||||
private void interactWithVersionCheckerMod( @Nonnull final String modFormatted, @Nonnull final String ghFormatted, @Nonnull final String changelog )
|
||||
{
|
||||
if( Loader.isModLoaded( "VersionChecker" ) )
|
||||
{
|
||||
final NBTTagCompound versionInf = new NBTTagCompound();
|
||||
versionInf.setString( "modDisplayName", AppEng.MOD_NAME );
|
||||
versionInf.setString( "oldVersion", modFormatted );
|
||||
versionInf.setString( "newVersion", ghFormatted );
|
||||
versionInf.setString( "updateUrl", "http://ae-mod.info/builds/appliedenergistics2-" + ghFormatted + ".jar" );
|
||||
versionInf.setBoolean( "isDirectLink", true );
|
||||
/**
|
||||
* Checks if the version checker mod is installed and handles it depending on that information
|
||||
*
|
||||
* @param modFormatted mod version formatted as rv2-beta-8
|
||||
* @param ghFormatted retrieved github version formatted as rv2-beta-8
|
||||
* @param changelog retrieved github changelog
|
||||
*/
|
||||
private void interactWithVersionCheckerMod(@Nonnull final String modFormatted, @Nonnull final String ghFormatted, @Nonnull final String changelog) {
|
||||
if (Loader.isModLoaded("VersionChecker")) {
|
||||
final NBTTagCompound versionInf = new NBTTagCompound();
|
||||
versionInf.setString("modDisplayName", AppEng.MOD_NAME);
|
||||
versionInf.setString("oldVersion", modFormatted);
|
||||
versionInf.setString("newVersion", ghFormatted);
|
||||
versionInf.setString("updateUrl", "http://ae-mod.info/builds/appliedenergistics2-" + ghFormatted + ".jar");
|
||||
versionInf.setBoolean("isDirectLink", true);
|
||||
|
||||
if( !changelog.isEmpty() )
|
||||
{
|
||||
versionInf.setString( "changeLog", changelog );
|
||||
}
|
||||
if (!changelog.isEmpty()) {
|
||||
versionInf.setString("changeLog", changelog);
|
||||
}
|
||||
|
||||
versionInf.setString( "newFileName", "appliedenergistics2-" + ghFormatted + ".jar" );
|
||||
FMLInterModComms.sendRuntimeMessage( AppEng.instance(), "VersionChecker", "addUpdate", versionInf );
|
||||
versionInf.setString("newFileName", "appliedenergistics2-" + ghFormatted + ".jar");
|
||||
FMLInterModComms.sendRuntimeMessage(AppEng.instance(), "VersionChecker", "addUpdate", versionInf);
|
||||
|
||||
AELog.info( "Reported new version to VersionChecker mod." );
|
||||
}
|
||||
else
|
||||
{
|
||||
AELog.info( "VersionChecker mod is not installed; Proceeding." );
|
||||
}
|
||||
}
|
||||
AELog.info("Reported new version to VersionChecker mod.");
|
||||
} else {
|
||||
AELog.info("VersionChecker mod is not installed; Proceeding.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,15 +19,13 @@
|
||||
package appeng.services.compass;
|
||||
|
||||
|
||||
public class CompassException extends RuntimeException
|
||||
{
|
||||
public class CompassException extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = 8825268683203860877L;
|
||||
private static final long serialVersionUID = 8825268683203860877L;
|
||||
|
||||
private final Throwable inner;
|
||||
private final Throwable inner;
|
||||
|
||||
public CompassException( final Throwable t )
|
||||
{
|
||||
this.inner = t;
|
||||
}
|
||||
public CompassException(final Throwable t) {
|
||||
this.inner = t;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,68 +19,59 @@
|
||||
package appeng.services.compass;
|
||||
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
public final class CompassReader {
|
||||
private final Map<Long, CompassRegion> regions = new HashMap<>(100);
|
||||
private final int dimensionId;
|
||||
private final File worldCompassFolder;
|
||||
|
||||
public CompassReader(final int dimensionId, @Nonnull final File worldCompassFolder) {
|
||||
Preconditions.checkNotNull(worldCompassFolder);
|
||||
Preconditions.checkArgument(worldCompassFolder.isDirectory());
|
||||
|
||||
public final class CompassReader
|
||||
{
|
||||
private final Map<Long, CompassRegion> regions = new HashMap<>( 100 );
|
||||
private final int dimensionId;
|
||||
private final File worldCompassFolder;
|
||||
this.dimensionId = dimensionId;
|
||||
this.worldCompassFolder = worldCompassFolder;
|
||||
}
|
||||
|
||||
public CompassReader( final int dimensionId, @Nonnull final File worldCompassFolder )
|
||||
{
|
||||
Preconditions.checkNotNull( worldCompassFolder );
|
||||
Preconditions.checkArgument( worldCompassFolder.isDirectory() );
|
||||
public void close() {
|
||||
for (final CompassRegion r : this.regions.values()) {
|
||||
r.close();
|
||||
}
|
||||
|
||||
this.dimensionId = dimensionId;
|
||||
this.worldCompassFolder = worldCompassFolder;
|
||||
}
|
||||
this.regions.clear();
|
||||
}
|
||||
|
||||
public void close()
|
||||
{
|
||||
for( final CompassRegion r : this.regions.values() )
|
||||
{
|
||||
r.close();
|
||||
}
|
||||
public void setHasBeacon(final int cx, final int cz, final int cdy, final boolean hasBeacon) {
|
||||
final CompassRegion r = this.getRegion(cx, cz);
|
||||
|
||||
this.regions.clear();
|
||||
}
|
||||
r.setHasBeacon(cx, cz, cdy, hasBeacon);
|
||||
}
|
||||
|
||||
public void setHasBeacon( final int cx, final int cz, final int cdy, final boolean hasBeacon )
|
||||
{
|
||||
final CompassRegion r = this.getRegion( cx, cz );
|
||||
public boolean hasBeacon(final int cx, final int cz) {
|
||||
final CompassRegion r = this.getRegion(cx, cz);
|
||||
|
||||
r.setHasBeacon( cx, cz, cdy, hasBeacon );
|
||||
}
|
||||
return r.hasBeacon(cx, cz);
|
||||
}
|
||||
|
||||
public boolean hasBeacon( final int cx, final int cz )
|
||||
{
|
||||
final CompassRegion r = this.getRegion( cx, cz );
|
||||
private CompassRegion getRegion(final int cx, final int cz) {
|
||||
long pos = cx >> 10;
|
||||
pos <<= 32;
|
||||
pos |= (cz >> 10);
|
||||
|
||||
return r.hasBeacon( cx, cz );
|
||||
}
|
||||
CompassRegion cr = this.regions.get(pos);
|
||||
|
||||
private CompassRegion getRegion( final int cx, final int cz )
|
||||
{
|
||||
long pos = cx >> 10;
|
||||
pos <<= 32;
|
||||
pos |= ( cz >> 10 );
|
||||
if (cr == null) {
|
||||
cr = new CompassRegion(cx, cz, this.dimensionId, this.worldCompassFolder);
|
||||
this.regions.put(pos, cr);
|
||||
}
|
||||
|
||||
CompassRegion cr = this.regions.get( pos );
|
||||
|
||||
if( cr == null )
|
||||
{
|
||||
cr = new CompassRegion( cx, cz, this.dimensionId, this.worldCompassFolder );
|
||||
this.regions.put( pos, cr );
|
||||
}
|
||||
|
||||
return cr;
|
||||
}
|
||||
return cr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,193 +19,150 @@
|
||||
package appeng.services.compass;
|
||||
|
||||
|
||||
import appeng.core.worlddata.MeteorDataNameEncoder;
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.io.File;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.FileChannel;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
public final class CompassRegion {
|
||||
private final int lowX;
|
||||
private final int lowZ;
|
||||
private final int world;
|
||||
private final File worldCompassFolder;
|
||||
private final MeteorDataNameEncoder encoder;
|
||||
|
||||
import appeng.core.worlddata.MeteorDataNameEncoder;
|
||||
private boolean hasFile = false;
|
||||
private RandomAccessFile raf = null;
|
||||
private ByteBuffer buffer;
|
||||
|
||||
public CompassRegion(final int cx, final int cz, final int worldID, @Nonnull final File worldCompassFolder) {
|
||||
Preconditions.checkNotNull(worldCompassFolder);
|
||||
Preconditions.checkArgument(worldCompassFolder.isDirectory());
|
||||
|
||||
public final class CompassRegion
|
||||
{
|
||||
private final int lowX;
|
||||
private final int lowZ;
|
||||
private final int world;
|
||||
private final File worldCompassFolder;
|
||||
private final MeteorDataNameEncoder encoder;
|
||||
this.world = worldID;
|
||||
this.worldCompassFolder = worldCompassFolder;
|
||||
this.encoder = new MeteorDataNameEncoder(0);
|
||||
|
||||
private boolean hasFile = false;
|
||||
private RandomAccessFile raf = null;
|
||||
private ByteBuffer buffer;
|
||||
final int region_x = cx >> 10;
|
||||
final int region_z = cz >> 10;
|
||||
|
||||
public CompassRegion( final int cx, final int cz, final int worldID, @Nonnull final File worldCompassFolder )
|
||||
{
|
||||
Preconditions.checkNotNull( worldCompassFolder );
|
||||
Preconditions.checkArgument( worldCompassFolder.isDirectory() );
|
||||
this.lowX = region_x << 10;
|
||||
this.lowZ = region_z << 10;
|
||||
|
||||
this.world = worldID;
|
||||
this.worldCompassFolder = worldCompassFolder;
|
||||
this.encoder = new MeteorDataNameEncoder( 0 );
|
||||
this.openFile(false);
|
||||
}
|
||||
|
||||
final int region_x = cx >> 10;
|
||||
final int region_z = cz >> 10;
|
||||
void close() {
|
||||
try {
|
||||
if (this.hasFile) {
|
||||
this.buffer = null;
|
||||
this.raf.close();
|
||||
this.raf = null;
|
||||
this.hasFile = false;
|
||||
}
|
||||
} catch (final Throwable t) {
|
||||
throw new CompassException(t);
|
||||
}
|
||||
}
|
||||
|
||||
this.lowX = region_x << 10;
|
||||
this.lowZ = region_z << 10;
|
||||
boolean hasBeacon(int cx, int cz) {
|
||||
if (this.hasFile) {
|
||||
cx &= 0x3FF;
|
||||
cz &= 0x3FF;
|
||||
|
||||
this.openFile( false );
|
||||
}
|
||||
final int val = this.read(cx, cz);
|
||||
return val != 0;
|
||||
}
|
||||
|
||||
void close()
|
||||
{
|
||||
try
|
||||
{
|
||||
if( this.hasFile )
|
||||
{
|
||||
this.buffer = null;
|
||||
this.raf.close();
|
||||
this.raf = null;
|
||||
this.hasFile = false;
|
||||
}
|
||||
}
|
||||
catch( final Throwable t )
|
||||
{
|
||||
throw new CompassException( t );
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean hasBeacon( int cx, int cz )
|
||||
{
|
||||
if( this.hasFile )
|
||||
{
|
||||
cx &= 0x3FF;
|
||||
cz &= 0x3FF;
|
||||
void setHasBeacon(int cx, int cz, final int cdy, final boolean hasBeacon) {
|
||||
cx &= 0x3FF;
|
||||
cz &= 0x3FF;
|
||||
|
||||
final int val = this.read( cx, cz );
|
||||
if( val != 0 )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
this.openFile(hasBeacon);
|
||||
|
||||
return false;
|
||||
}
|
||||
if (this.hasFile) {
|
||||
int val = this.read(cx, cz);
|
||||
final int originalVal = val;
|
||||
|
||||
void setHasBeacon( int cx, int cz, final int cdy, final boolean hasBeacon )
|
||||
{
|
||||
cx &= 0x3FF;
|
||||
cz &= 0x3FF;
|
||||
if (hasBeacon) {
|
||||
val |= 1 << cdy;
|
||||
} else {
|
||||
val &= ~(1 << cdy);
|
||||
}
|
||||
|
||||
this.openFile( hasBeacon );
|
||||
if (originalVal != val) {
|
||||
this.write(cx, cz, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( this.hasFile )
|
||||
{
|
||||
int val = this.read( cx, cz );
|
||||
final int originalVal = val;
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
try {
|
||||
if (this.raf != null) {
|
||||
this.raf.close();
|
||||
}
|
||||
} finally {
|
||||
super.finalize();
|
||||
}
|
||||
|
||||
if( hasBeacon )
|
||||
{
|
||||
val |= 1 << cdy;
|
||||
}
|
||||
else
|
||||
{
|
||||
val &= ~( 1 << cdy );
|
||||
}
|
||||
}
|
||||
|
||||
if( originalVal != val )
|
||||
{
|
||||
this.write( cx, cz, val );
|
||||
}
|
||||
}
|
||||
}
|
||||
private void openFile(final boolean create) {
|
||||
if (this.hasFile) {
|
||||
return;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable
|
||||
{
|
||||
try
|
||||
{
|
||||
if( this.raf != null )
|
||||
{
|
||||
this.raf.close();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
super.finalize();
|
||||
}
|
||||
final File file = this.getFile();
|
||||
if (create || this.isFileExistent(file)) {
|
||||
try {
|
||||
this.raf = new RandomAccessFile(file, "rw");
|
||||
final FileChannel fc = this.raf.getChannel();
|
||||
this.buffer = fc.map(FileChannel.MapMode.READ_WRITE, 0, 0x400 * 0x400);// fc.size() );
|
||||
this.hasFile = true;
|
||||
} catch (final Throwable t) {
|
||||
throw new CompassException(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
private File getFile() {
|
||||
final String fileName = this.encoder.encode(this.world, this.lowX, this.lowZ);
|
||||
|
||||
private void openFile( final boolean create )
|
||||
{
|
||||
if( this.hasFile )
|
||||
{
|
||||
return;
|
||||
}
|
||||
return new File(this.worldCompassFolder, fileName);
|
||||
}
|
||||
|
||||
final File file = this.getFile();
|
||||
if( create || this.isFileExistent( file ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
this.raf = new RandomAccessFile( file, "rw" );
|
||||
final FileChannel fc = this.raf.getChannel();
|
||||
this.buffer = fc.map( FileChannel.MapMode.READ_WRITE, 0, 0x400 * 0x400 );// fc.size() );
|
||||
this.hasFile = true;
|
||||
}
|
||||
catch( final Throwable t )
|
||||
{
|
||||
throw new CompassException( t );
|
||||
}
|
||||
}
|
||||
}
|
||||
private boolean isFileExistent(final File file) {
|
||||
return file.exists() && file.isFile();
|
||||
}
|
||||
|
||||
private File getFile()
|
||||
{
|
||||
final String fileName = this.encoder.encode( this.world, this.lowX, this.lowZ );
|
||||
private int read(final int cx, final int cz) {
|
||||
try {
|
||||
return this.buffer.get(cx + cz * 0x400);
|
||||
// raf.seek( cx + cz * 0x400 );
|
||||
// return raf.readByte();
|
||||
} catch (final IndexOutOfBoundsException outOfBounds) {
|
||||
return 0;
|
||||
} catch (final Throwable t) {
|
||||
throw new CompassException(t);
|
||||
}
|
||||
}
|
||||
|
||||
return new File( this.worldCompassFolder, fileName );
|
||||
}
|
||||
|
||||
private boolean isFileExistent( final File file )
|
||||
{
|
||||
return file.exists() && file.isFile();
|
||||
}
|
||||
|
||||
private int read( final int cx, final int cz )
|
||||
{
|
||||
try
|
||||
{
|
||||
return this.buffer.get( cx + cz * 0x400 );
|
||||
// raf.seek( cx + cz * 0x400 );
|
||||
// return raf.readByte();
|
||||
}
|
||||
catch( final IndexOutOfBoundsException outOfBounds )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
catch( final Throwable t )
|
||||
{
|
||||
throw new CompassException( t );
|
||||
}
|
||||
}
|
||||
|
||||
private void write( final int cx, final int cz, final int val )
|
||||
{
|
||||
try
|
||||
{
|
||||
this.buffer.put( cx + cz * 0x400, (byte) val );
|
||||
// raf.seek( cx + cz * 0x400 );
|
||||
// raf.writeByte( val );
|
||||
}
|
||||
catch( final Throwable t )
|
||||
{
|
||||
throw new CompassException( t );
|
||||
}
|
||||
}
|
||||
private void write(final int cx, final int cz, final int val) {
|
||||
try {
|
||||
this.buffer.put(cx + cz * 0x400, (byte) val);
|
||||
// raf.seek( cx + cz * 0x400 );
|
||||
// raf.writeByte( val );
|
||||
} catch (final Throwable t) {
|
||||
throw new CompassException(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,11 +19,10 @@
|
||||
package appeng.services.compass;
|
||||
|
||||
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
|
||||
|
||||
/**
|
||||
@@ -31,13 +30,11 @@ import com.google.common.base.Preconditions;
|
||||
* @version rv3 - 31.05.2015
|
||||
* @since rv3 31.05.2015
|
||||
*/
|
||||
public final class CompassThreadFactory implements ThreadFactory
|
||||
{
|
||||
@Override
|
||||
public Thread newThread( @Nonnull final Runnable job )
|
||||
{
|
||||
Preconditions.checkNotNull( job );
|
||||
public final class CompassThreadFactory implements ThreadFactory {
|
||||
@Override
|
||||
public Thread newThread(@Nonnull final Runnable job) {
|
||||
Preconditions.checkNotNull(job);
|
||||
|
||||
return new Thread( job, "AE Compass Service" );
|
||||
}
|
||||
return new Thread(job, "AE Compass Service");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,16 +19,15 @@
|
||||
package appeng.services.compass;
|
||||
|
||||
|
||||
public interface ICompassCallback
|
||||
{
|
||||
public interface ICompassCallback {
|
||||
|
||||
/**
|
||||
* Called from another thread.
|
||||
*
|
||||
* @param hasResult true if found a target
|
||||
* @param spin true if should spin
|
||||
* @param radians radians
|
||||
* @param dist distance
|
||||
*/
|
||||
void calculatedDirection( boolean hasResult, boolean spin, double radians, double dist );
|
||||
/**
|
||||
* Called from another thread.
|
||||
*
|
||||
* @param hasResult true if found a target
|
||||
* @param spin true if should spin
|
||||
* @param radians radians
|
||||
* @param dist distance
|
||||
*/
|
||||
void calculatedDirection(boolean hasResult, boolean spin, double radians, double dist);
|
||||
}
|
||||
|
||||
@@ -27,15 +27,14 @@ package appeng.services.export;
|
||||
* @see Checker
|
||||
* @since rv3 - 25.09.2015
|
||||
*/
|
||||
enum CheckType
|
||||
{
|
||||
/**
|
||||
* If checking resulted in both objects being <b>equal</b>
|
||||
*/
|
||||
EQUAL,
|
||||
enum CheckType {
|
||||
/**
|
||||
* If checking resulted in both objects being <b>equal</b>
|
||||
*/
|
||||
EQUAL,
|
||||
|
||||
/**
|
||||
* If checking resulted in both objects being <b>unequal</b>
|
||||
*/
|
||||
UNEQUAL
|
||||
/**
|
||||
* If checking resulted in both objects being <b>unequal</b>
|
||||
*/
|
||||
UNEQUAL
|
||||
}
|
||||
|
||||
@@ -24,22 +24,19 @@ import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* Checks against a specific type with its own check type for clear outcome.
|
||||
*
|
||||
* <p>
|
||||
* The constructor will generally have a value which the checker will check against
|
||||
*
|
||||
* @author thatsIch
|
||||
* @version rv3 - 01.09.2015
|
||||
* @since rv3 - 01.09.2015
|
||||
*/
|
||||
interface Checker<T>
|
||||
{
|
||||
/**
|
||||
* @param checkedAgainst the object it is checked against
|
||||
*
|
||||
* @return non null being either equal or unequal
|
||||
*
|
||||
* @since rv3 - 01.09.2015
|
||||
*/
|
||||
@Nonnull
|
||||
CheckType isEqual( @Nonnull final T checkedAgainst );
|
||||
interface Checker<T> {
|
||||
/**
|
||||
* @param checkedAgainst the object it is checked against
|
||||
* @return non null being either equal or unequal
|
||||
* @since rv3 - 01.09.2015
|
||||
*/
|
||||
@Nonnull
|
||||
CheckType isEqual(@Nonnull final T checkedAgainst);
|
||||
}
|
||||
|
||||
@@ -27,56 +27,55 @@ import javax.annotation.Nonnull;
|
||||
* @version rv3 - 14.08.2015
|
||||
* @since rv3 14.08.2015
|
||||
*/
|
||||
public interface ExportConfig
|
||||
{
|
||||
/**
|
||||
* config switch to disable the exporting.
|
||||
* if the recipes system is not used
|
||||
* there is no reason to export them.
|
||||
* Still can be useful for debugging purpose,
|
||||
* thus not tying it to the recipe system directly.
|
||||
*
|
||||
* @return true if exporting is enabled
|
||||
*/
|
||||
boolean isExportingItemNamesEnabled();
|
||||
public interface ExportConfig {
|
||||
/**
|
||||
* config switch to disable the exporting.
|
||||
* if the recipes system is not used
|
||||
* there is no reason to export them.
|
||||
* Still can be useful for debugging purpose,
|
||||
* thus not tying it to the recipe system directly.
|
||||
*
|
||||
* @return true if exporting is enabled
|
||||
*/
|
||||
boolean isExportingItemNamesEnabled();
|
||||
|
||||
/**
|
||||
* config switch for using the digest cache.
|
||||
*
|
||||
* @return true if cache is enabled
|
||||
*/
|
||||
boolean isCacheEnabled();
|
||||
/**
|
||||
* config switch for using the digest cache.
|
||||
*
|
||||
* @return true if cache is enabled
|
||||
*/
|
||||
boolean isCacheEnabled();
|
||||
|
||||
/**
|
||||
* config switch to always refresh the CSV. Might be useful to activate on debugging.
|
||||
*
|
||||
* @return true if force refresh is enabled
|
||||
*/
|
||||
boolean isForceRefreshEnabled();
|
||||
/**
|
||||
* config switch to always refresh the CSV. Might be useful to activate on debugging.
|
||||
*
|
||||
* @return true if force refresh is enabled
|
||||
*/
|
||||
boolean isForceRefreshEnabled();
|
||||
|
||||
/**
|
||||
* config switch to export more information mostly used for debugging
|
||||
*
|
||||
* @return true if additional information are enabled
|
||||
*/
|
||||
boolean isAdditionalInformationEnabled();
|
||||
/**
|
||||
* config switch to export more information mostly used for debugging
|
||||
*
|
||||
* @return true if additional information are enabled
|
||||
*/
|
||||
boolean isAdditionalInformationEnabled();
|
||||
|
||||
/**
|
||||
* Will get the cache from last session. Can be used to reduce I/O operations though containing itself calculation.
|
||||
*
|
||||
* @return a digest from the last calculation
|
||||
*/
|
||||
String getCache();
|
||||
/**
|
||||
* Will get the cache from last session. Can be used to reduce I/O operations though containing itself calculation.
|
||||
*
|
||||
* @return a digest from the last calculation
|
||||
*/
|
||||
String getCache();
|
||||
|
||||
/**
|
||||
* sets the cache for the next session to reduce calculation overhead
|
||||
*
|
||||
* @param digest new digest for the cache
|
||||
*/
|
||||
void setCache( @Nonnull String digest );
|
||||
/**
|
||||
* sets the cache for the next session to reduce calculation overhead
|
||||
*
|
||||
* @param digest new digest for the cache
|
||||
*/
|
||||
void setCache(@Nonnull String digest);
|
||||
|
||||
/**
|
||||
* Will delegate the saving
|
||||
*/
|
||||
void save();
|
||||
/**
|
||||
* Will delegate the saving
|
||||
*/
|
||||
void save();
|
||||
}
|
||||
|
||||
@@ -21,22 +21,21 @@ package appeng.services.export;
|
||||
|
||||
/**
|
||||
* Defines the different modes which need to be distinguished upon exporting.
|
||||
*
|
||||
* <p>
|
||||
* using a different mode will result in a different export outcome.
|
||||
*
|
||||
* @author thatsIch
|
||||
* @version rv3 - 23.09.2015
|
||||
* @since rv3 - 23.09.2015
|
||||
*/
|
||||
enum ExportMode
|
||||
{
|
||||
/**
|
||||
* Will provide general users with information required for recipe making
|
||||
*/
|
||||
MINIMAL,
|
||||
enum ExportMode {
|
||||
/**
|
||||
* Will provide general users with information required for recipe making
|
||||
*/
|
||||
MINIMAL,
|
||||
|
||||
/**
|
||||
* Will provide advanced users with information with debugging functionality
|
||||
*/
|
||||
VERBOSE
|
||||
/**
|
||||
* Will provide advanced users with information with debugging functionality
|
||||
*/
|
||||
VERBOSE
|
||||
}
|
||||
|
||||
@@ -19,112 +19,97 @@
|
||||
package appeng.services.export;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import appeng.core.AELog;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.base.Stopwatch;
|
||||
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraftforge.fml.common.Loader;
|
||||
import net.minecraftforge.fml.common.ModContainer;
|
||||
import net.minecraftforge.fml.common.registry.ForgeRegistries;
|
||||
import net.minecraftforge.registries.IForgeRegistry;
|
||||
|
||||
import appeng.core.AELog;
|
||||
import javax.annotation.Nonnull;
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
|
||||
/**
|
||||
* Main entry point for exporting the CSV file
|
||||
*
|
||||
* <p>
|
||||
* makes everything threadable
|
||||
*
|
||||
* @author thatsIch
|
||||
* @version rv3 - 14.08.2015
|
||||
* @since rv3 14.08.2015
|
||||
*/
|
||||
public class ExportProcess implements Runnable
|
||||
{
|
||||
private static final String FORCE_REFRESH_MESSAGE = "Force Refresh enabled. Will ignore cache and export CSV content.";
|
||||
private static final String CACHE_ENABLED_MESSAGE = "Cache is enabled. Checking for new mod configurations.";
|
||||
private static final String EQUAL_CONTENT_MESSAGE = "Same mod configuration was found. Not updating CSV content.";
|
||||
private static final String UNEQUAL_CONTENT_MESSAGE = "New mod configuration was found. Commencing exporting.";
|
||||
private static final String CACHE_DISABLED_MESSAGE = "Cache is disabled. Commencing exporting.";
|
||||
private static final String EXPORT_START_MESSAGE = "Item Exporting ( started )";
|
||||
private static final String EXPORT_END_MESSAGE = "Item Exporting ( ended after %s ms)";
|
||||
public class ExportProcess implements Runnable {
|
||||
private static final String FORCE_REFRESH_MESSAGE = "Force Refresh enabled. Will ignore cache and export CSV content.";
|
||||
private static final String CACHE_ENABLED_MESSAGE = "Cache is enabled. Checking for new mod configurations.";
|
||||
private static final String EQUAL_CONTENT_MESSAGE = "Same mod configuration was found. Not updating CSV content.";
|
||||
private static final String UNEQUAL_CONTENT_MESSAGE = "New mod configuration was found. Commencing exporting.";
|
||||
private static final String CACHE_DISABLED_MESSAGE = "Cache is disabled. Commencing exporting.";
|
||||
private static final String EXPORT_START_MESSAGE = "Item Exporting ( started )";
|
||||
private static final String EXPORT_END_MESSAGE = "Item Exporting ( ended after %s ms)";
|
||||
|
||||
@Nonnull
|
||||
private final File exportDirectory;
|
||||
@Nonnull
|
||||
private final Checker<List<ModContainer>> modChecker;
|
||||
@Nonnull
|
||||
private final ExportConfig config;
|
||||
@Nonnull
|
||||
private final File exportDirectory;
|
||||
@Nonnull
|
||||
private final Checker<List<ModContainer>> modChecker;
|
||||
@Nonnull
|
||||
private final ExportConfig config;
|
||||
|
||||
/**
|
||||
* @param exportDirectory directory where the final CSV file will be exported to
|
||||
* @param config configuration to manipulate the export process
|
||||
*/
|
||||
public ExportProcess( @Nonnull final File exportDirectory, @Nonnull final ExportConfig config )
|
||||
{
|
||||
this.exportDirectory = Preconditions.checkNotNull( exportDirectory );
|
||||
this.config = Preconditions.checkNotNull( config );
|
||||
/**
|
||||
* @param exportDirectory directory where the final CSV file will be exported to
|
||||
* @param config configuration to manipulate the export process
|
||||
*/
|
||||
public ExportProcess(@Nonnull final File exportDirectory, @Nonnull final ExportConfig config) {
|
||||
this.exportDirectory = Preconditions.checkNotNull(exportDirectory);
|
||||
this.config = Preconditions.checkNotNull(config);
|
||||
|
||||
this.modChecker = new ModListChecker( config );
|
||||
}
|
||||
this.modChecker = new ModListChecker(config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will check and export if various config settings will lead to exporting the CSV file.
|
||||
*/
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
// no priority to this thread
|
||||
Thread.yield();
|
||||
/**
|
||||
* Will check and export if various config settings will lead to exporting the CSV file.
|
||||
*/
|
||||
@Override
|
||||
public void run() {
|
||||
// no priority to this thread
|
||||
Thread.yield();
|
||||
|
||||
// logic when to cancel the export process
|
||||
if( this.config.isForceRefreshEnabled() )
|
||||
{
|
||||
AELog.info( FORCE_REFRESH_MESSAGE );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( this.config.isCacheEnabled() )
|
||||
{
|
||||
AELog.info( CACHE_ENABLED_MESSAGE );
|
||||
// logic when to cancel the export process
|
||||
if (this.config.isForceRefreshEnabled()) {
|
||||
AELog.info(FORCE_REFRESH_MESSAGE);
|
||||
} else {
|
||||
if (this.config.isCacheEnabled()) {
|
||||
AELog.info(CACHE_ENABLED_MESSAGE);
|
||||
|
||||
final Loader loader = Loader.instance();
|
||||
final List<ModContainer> mods = loader.getActiveModList();
|
||||
final Loader loader = Loader.instance();
|
||||
final List<ModContainer> mods = loader.getActiveModList();
|
||||
|
||||
if( this.modChecker.isEqual( mods ) == CheckType.EQUAL )
|
||||
{
|
||||
AELog.info( EQUAL_CONTENT_MESSAGE );
|
||||
if (this.modChecker.isEqual(mods) == CheckType.EQUAL) {
|
||||
AELog.info(EQUAL_CONTENT_MESSAGE);
|
||||
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
AELog.info( UNEQUAL_CONTENT_MESSAGE );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AELog.info( CACHE_DISABLED_MESSAGE );
|
||||
}
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
AELog.info(UNEQUAL_CONTENT_MESSAGE);
|
||||
}
|
||||
} else {
|
||||
AELog.info(CACHE_DISABLED_MESSAGE);
|
||||
}
|
||||
}
|
||||
|
||||
AELog.info( EXPORT_START_MESSAGE );
|
||||
final Stopwatch watch = Stopwatch.createStarted();
|
||||
AELog.info(EXPORT_START_MESSAGE);
|
||||
final Stopwatch watch = Stopwatch.createStarted();
|
||||
|
||||
final IForgeRegistry<Item> itemRegistry = ForgeRegistries.ITEMS;
|
||||
final IForgeRegistry<Item> itemRegistry = ForgeRegistries.ITEMS;
|
||||
|
||||
final ExportMode mode = this.config.isAdditionalInformationEnabled() ? ExportMode.VERBOSE : ExportMode.MINIMAL;
|
||||
final Exporter exporter = new MinecraftItemCSVExporter( this.exportDirectory, itemRegistry, mode );
|
||||
final ExportMode mode = this.config.isAdditionalInformationEnabled() ? ExportMode.VERBOSE : ExportMode.MINIMAL;
|
||||
final Exporter exporter = new MinecraftItemCSVExporter(this.exportDirectory, itemRegistry, mode);
|
||||
|
||||
exporter.export();
|
||||
exporter.export();
|
||||
|
||||
AELog.info( EXPORT_END_MESSAGE, watch.elapsed( TimeUnit.MILLISECONDS ) );
|
||||
}
|
||||
AELog.info(EXPORT_END_MESSAGE, watch.elapsed(TimeUnit.MILLISECONDS));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,10 +26,9 @@ package appeng.services.export;
|
||||
* @version rv3 - 19.08.2015
|
||||
* @since rv3 19.08.2015
|
||||
*/
|
||||
interface Exporter
|
||||
{
|
||||
/**
|
||||
* Will export something defined by the Exporter with side effects
|
||||
*/
|
||||
void export();
|
||||
interface Exporter {
|
||||
/**
|
||||
* Will export something defined by the Exporter with side effects
|
||||
*/
|
||||
void export();
|
||||
}
|
||||
|
||||
@@ -19,13 +19,12 @@
|
||||
package appeng.services.export;
|
||||
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
import net.minecraftforge.common.config.Configuration;
|
||||
import net.minecraftforge.common.config.Property;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
|
||||
/**
|
||||
* Offers configuration switches for the user to change the export process
|
||||
@@ -34,100 +33,91 @@ import net.minecraftforge.common.config.Property;
|
||||
* @version rv3 - 14.08.2015
|
||||
* @since rv3 14.08.2015
|
||||
*/
|
||||
public final class ForgeExportConfig implements ExportConfig
|
||||
{
|
||||
private static final String GENERAL_CATEGORY = "general";
|
||||
private static final String CACHE_CATEGORY = "cache";
|
||||
public final class ForgeExportConfig implements ExportConfig {
|
||||
private static final String GENERAL_CATEGORY = "general";
|
||||
private static final String CACHE_CATEGORY = "cache";
|
||||
|
||||
private static final String EXPORT_ITEM_NAMES_KEY = "exportItemNames";
|
||||
private static final boolean EXPORT_ITEM_NAMES_DEFAULT = true;
|
||||
private static final String EXPORT_ITEM_NAMES_DESCRIPTION = "If true, all registered items will be exported containing the internal minecraft name and the localized name to actually find the item you are using. This also contains the item representation of the blocks, but are missing items, which are too much to display e.g. FMP.";
|
||||
private static final String EXPORT_ITEM_NAMES_KEY = "exportItemNames";
|
||||
private static final boolean EXPORT_ITEM_NAMES_DEFAULT = true;
|
||||
private static final String EXPORT_ITEM_NAMES_DESCRIPTION = "If true, all registered items will be exported containing the internal minecraft name and the localized name to actually find the item you are using. This also contains the item representation of the blocks, but are missing items, which are too much to display e.g. FMP.";
|
||||
|
||||
private static final String ENABLE_FORCE_REFRESH_KEY = "enableForceRefresh";
|
||||
private static final boolean ENABLE_FORCE_REFRESH_DEFAULT = false;
|
||||
private static final String ENABLE_FORCE_REFRESH_DESCRIPTION = "If true, the CSV exporting will always happen. This will not use the cache to reduce the computation.";
|
||||
private static final String ENABLE_FORCE_REFRESH_KEY = "enableForceRefresh";
|
||||
private static final boolean ENABLE_FORCE_REFRESH_DEFAULT = false;
|
||||
private static final String ENABLE_FORCE_REFRESH_DESCRIPTION = "If true, the CSV exporting will always happen. This will not use the cache to reduce the computation.";
|
||||
|
||||
private static final String ENABLE_CACHE_KEY = "enableCache";
|
||||
private static final boolean ENABLE_CACHE_DEFAULT = true;
|
||||
private static final String ENABLE_CACHE_DESCRIPTION = "Caching can save processing time, if there are a lot of items.";
|
||||
private static final String ENABLE_CACHE_KEY = "enableCache";
|
||||
private static final boolean ENABLE_CACHE_DEFAULT = true;
|
||||
private static final String ENABLE_CACHE_DESCRIPTION = "Caching can save processing time, if there are a lot of items.";
|
||||
|
||||
private static final String ENABLE_ADDITIONAL_INFO_KEY = "enableAdditionalInfo";
|
||||
private static final boolean ENABLE_ADDITIONAL_INFO_DEFAULT = false;
|
||||
private static final String ENABLE_ADDITIONAL_INFO_DESCRIPTION = "Will output more detailed information into the CSV like corresponding items";
|
||||
private static final String ENABLE_ADDITIONAL_INFO_KEY = "enableAdditionalInfo";
|
||||
private static final boolean ENABLE_ADDITIONAL_INFO_DEFAULT = false;
|
||||
private static final String ENABLE_ADDITIONAL_INFO_DESCRIPTION = "Will output more detailed information into the CSV like corresponding items";
|
||||
|
||||
private static final String DIGEST_KEY = "digest";
|
||||
private static final String DIGEST_DEFAULT = "";
|
||||
private static final String DIGEST_DESCRIPTION = "Digest of all the mods and versions to check if a re-export of the item names is required.";
|
||||
private static final String DIGEST_KEY = "digest";
|
||||
private static final String DIGEST_DEFAULT = "";
|
||||
private static final String DIGEST_DESCRIPTION = "Digest of all the mods and versions to check if a re-export of the item names is required.";
|
||||
|
||||
private final boolean exportItemNamesEnabled;
|
||||
private final boolean cacheEnabled;
|
||||
private final boolean forceRefreshEnabled;
|
||||
private final boolean additionalInformationEnabled;
|
||||
private final String cache;
|
||||
private final Configuration config;
|
||||
private final boolean exportItemNamesEnabled;
|
||||
private final boolean cacheEnabled;
|
||||
private final boolean forceRefreshEnabled;
|
||||
private final boolean additionalInformationEnabled;
|
||||
private final String cache;
|
||||
private final Configuration config;
|
||||
|
||||
/**
|
||||
* Constructor using the configuration. Apparently there are some race conditions if constructing configurations on
|
||||
* multiple file accesses
|
||||
*
|
||||
* @param config to be wrapped configuration.
|
||||
*/
|
||||
public ForgeExportConfig( @Nonnull final Configuration config )
|
||||
{
|
||||
this.config = Preconditions.checkNotNull( config );
|
||||
/**
|
||||
* Constructor using the configuration. Apparently there are some race conditions if constructing configurations on
|
||||
* multiple file accesses
|
||||
*
|
||||
* @param config to be wrapped configuration.
|
||||
*/
|
||||
public ForgeExportConfig(@Nonnull final Configuration config) {
|
||||
this.config = Preconditions.checkNotNull(config);
|
||||
|
||||
this.exportItemNamesEnabled = this.config.getBoolean( EXPORT_ITEM_NAMES_KEY, GENERAL_CATEGORY, EXPORT_ITEM_NAMES_DEFAULT,
|
||||
EXPORT_ITEM_NAMES_DESCRIPTION );
|
||||
this.cacheEnabled = this.config.getBoolean( ENABLE_CACHE_KEY, CACHE_CATEGORY, ENABLE_CACHE_DEFAULT, ENABLE_CACHE_DESCRIPTION );
|
||||
this.additionalInformationEnabled = this.config.getBoolean( ENABLE_ADDITIONAL_INFO_KEY, GENERAL_CATEGORY, ENABLE_ADDITIONAL_INFO_DEFAULT,
|
||||
ENABLE_ADDITIONAL_INFO_DESCRIPTION );
|
||||
this.cache = this.config.getString( DIGEST_KEY, CACHE_CATEGORY, DIGEST_DEFAULT, DIGEST_DESCRIPTION );
|
||||
this.forceRefreshEnabled = this.config.getBoolean( ENABLE_FORCE_REFRESH_KEY, GENERAL_CATEGORY, ENABLE_FORCE_REFRESH_DEFAULT,
|
||||
ENABLE_FORCE_REFRESH_DESCRIPTION );
|
||||
}
|
||||
this.exportItemNamesEnabled = this.config.getBoolean(EXPORT_ITEM_NAMES_KEY, GENERAL_CATEGORY, EXPORT_ITEM_NAMES_DEFAULT,
|
||||
EXPORT_ITEM_NAMES_DESCRIPTION);
|
||||
this.cacheEnabled = this.config.getBoolean(ENABLE_CACHE_KEY, CACHE_CATEGORY, ENABLE_CACHE_DEFAULT, ENABLE_CACHE_DESCRIPTION);
|
||||
this.additionalInformationEnabled = this.config.getBoolean(ENABLE_ADDITIONAL_INFO_KEY, GENERAL_CATEGORY, ENABLE_ADDITIONAL_INFO_DEFAULT,
|
||||
ENABLE_ADDITIONAL_INFO_DESCRIPTION);
|
||||
this.cache = this.config.getString(DIGEST_KEY, CACHE_CATEGORY, DIGEST_DEFAULT, DIGEST_DESCRIPTION);
|
||||
this.forceRefreshEnabled = this.config.getBoolean(ENABLE_FORCE_REFRESH_KEY, GENERAL_CATEGORY, ENABLE_FORCE_REFRESH_DEFAULT,
|
||||
ENABLE_FORCE_REFRESH_DESCRIPTION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isExportingItemNamesEnabled()
|
||||
{
|
||||
return this.exportItemNamesEnabled;
|
||||
}
|
||||
@Override
|
||||
public boolean isExportingItemNamesEnabled() {
|
||||
return this.exportItemNamesEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCacheEnabled()
|
||||
{
|
||||
return this.cacheEnabled;
|
||||
}
|
||||
@Override
|
||||
public boolean isCacheEnabled() {
|
||||
return this.cacheEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isForceRefreshEnabled()
|
||||
{
|
||||
return this.forceRefreshEnabled;
|
||||
}
|
||||
@Override
|
||||
public boolean isForceRefreshEnabled() {
|
||||
return this.forceRefreshEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAdditionalInformationEnabled()
|
||||
{
|
||||
return this.additionalInformationEnabled;
|
||||
}
|
||||
@Override
|
||||
public boolean isAdditionalInformationEnabled() {
|
||||
return this.additionalInformationEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCache()
|
||||
{
|
||||
return this.cache;
|
||||
}
|
||||
@Override
|
||||
public String getCache() {
|
||||
return this.cache;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCache( @Nonnull final String digest )
|
||||
{
|
||||
final Property digestProperty = this.config.get( CACHE_CATEGORY, DIGEST_KEY, DIGEST_DEFAULT );
|
||||
digestProperty.set( digest );
|
||||
@Override
|
||||
public void setCache(@Nonnull final String digest) {
|
||||
final Property digestProperty = this.config.get(CACHE_CATEGORY, DIGEST_KEY, DIGEST_DEFAULT);
|
||||
digestProperty.set(digest);
|
||||
|
||||
this.config.save();
|
||||
}
|
||||
this.config.save();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save()
|
||||
{
|
||||
this.config.save();
|
||||
}
|
||||
@Override
|
||||
public void save() {
|
||||
this.config.save();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,25 +19,11 @@
|
||||
package appeng.services.export;
|
||||
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import appeng.core.AELog;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.creativetab.CreativeTabs;
|
||||
import net.minecraft.init.Blocks;
|
||||
@@ -47,8 +33,14 @@ import net.minecraft.util.NonNullList;
|
||||
import net.minecraft.util.text.translation.I18n;
|
||||
import net.minecraftforge.fml.common.registry.ForgeRegistries;
|
||||
import net.minecraftforge.registries.IForgeRegistry;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
|
||||
import appeng.core.AELog;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.*;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
@@ -58,234 +50,209 @@ import appeng.core.AELog;
|
||||
* @version rv3 - 14.08.2015
|
||||
* @since rv3 14.08.2015
|
||||
*/
|
||||
final class MinecraftItemCSVExporter implements Exporter
|
||||
{
|
||||
private static final String ITEM_CSV_FILE_NAME = "items.csv";
|
||||
private static final String MINIMAL_HEADER = "Mod:Item:MetaData, Localized Name";
|
||||
private static final String VERBOSE_HEADER = MINIMAL_HEADER + ", Unlocalized Name, Is Block?, Class Name";
|
||||
private static final String EXPORT_SUCCESSFUL_MESSAGE = "Exported successfully %d items into %s";
|
||||
private static final String EXPORT_UNSUCCESSFUL_MESSAGE = "Exporting was unsuccessful.";
|
||||
final class MinecraftItemCSVExporter implements Exporter {
|
||||
private static final String ITEM_CSV_FILE_NAME = "items.csv";
|
||||
private static final String MINIMAL_HEADER = "Mod:Item:MetaData, Localized Name";
|
||||
private static final String VERBOSE_HEADER = MINIMAL_HEADER + ", Unlocalized Name, Is Block?, Class Name";
|
||||
private static final String EXPORT_SUCCESSFUL_MESSAGE = "Exported successfully %d items into %s";
|
||||
private static final String EXPORT_UNSUCCESSFUL_MESSAGE = "Exporting was unsuccessful.";
|
||||
|
||||
@Nonnull
|
||||
private final File exportDirectory;
|
||||
@Nonnull
|
||||
private final IForgeRegistry<Item> itemRegistry;
|
||||
@Nonnull
|
||||
private final ExportMode mode;
|
||||
@Nonnull
|
||||
private final File exportDirectory;
|
||||
@Nonnull
|
||||
private final IForgeRegistry<Item> itemRegistry;
|
||||
@Nonnull
|
||||
private final ExportMode mode;
|
||||
|
||||
/**
|
||||
* @param exportDirectory directory of the resulting export file. Non-null required.
|
||||
* @param itemRegistry the registry with minecraft items. Needs to be populated at that time, thus the exporting can
|
||||
* only happen in init (pre-init is the
|
||||
* phase when all items are determined)
|
||||
* @param mode mode in which the export should be operated. Resulting CSV will change depending on this.
|
||||
*/
|
||||
MinecraftItemCSVExporter( @Nonnull final File exportDirectory, @Nonnull final IForgeRegistry<Item> itemRegistry, @Nonnull final ExportMode mode )
|
||||
{
|
||||
this.exportDirectory = Preconditions.checkNotNull( exportDirectory );
|
||||
Preconditions.checkArgument( !exportDirectory.isFile() );
|
||||
this.itemRegistry = Preconditions.checkNotNull( itemRegistry );
|
||||
this.mode = Preconditions.checkNotNull( mode );
|
||||
}
|
||||
/**
|
||||
* @param exportDirectory directory of the resulting export file. Non-null required.
|
||||
* @param itemRegistry the registry with minecraft items. Needs to be populated at that time, thus the exporting can
|
||||
* only happen in init (pre-init is the
|
||||
* phase when all items are determined)
|
||||
* @param mode mode in which the export should be operated. Resulting CSV will change depending on this.
|
||||
*/
|
||||
MinecraftItemCSVExporter(@Nonnull final File exportDirectory, @Nonnull final IForgeRegistry<Item> itemRegistry, @Nonnull final ExportMode mode) {
|
||||
this.exportDirectory = Preconditions.checkNotNull(exportDirectory);
|
||||
Preconditions.checkArgument(!exportDirectory.isFile());
|
||||
this.itemRegistry = Preconditions.checkNotNull(itemRegistry);
|
||||
this.mode = Preconditions.checkNotNull(mode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void export()
|
||||
{
|
||||
final Iterable<Item> items = this.itemRegistry;
|
||||
final List<Item> itemList = Lists.newArrayList( items );
|
||||
@Override
|
||||
public void export() {
|
||||
final Iterable<Item> items = this.itemRegistry;
|
||||
final List<Item> itemList = Lists.newArrayList(items);
|
||||
|
||||
final List<String> lines = Lists.transform( itemList, new ItemRowExtractFunction( this.itemRegistry, this.mode ) );
|
||||
final List<String> lines = Lists.transform(itemList, new ItemRowExtractFunction(this.itemRegistry, this.mode));
|
||||
|
||||
final Joiner newLineJoiner = Joiner.on( '\n' );
|
||||
final Joiner newLineJoinerIgnoringNull = newLineJoiner.skipNulls();
|
||||
final String joined = newLineJoinerIgnoringNull.join( lines );
|
||||
final Joiner newLineJoiner = Joiner.on('\n');
|
||||
final Joiner newLineJoinerIgnoringNull = newLineJoiner.skipNulls();
|
||||
final String joined = newLineJoinerIgnoringNull.join(lines);
|
||||
|
||||
final File file = new File( this.exportDirectory, ITEM_CSV_FILE_NAME );
|
||||
final File file = new File(this.exportDirectory, ITEM_CSV_FILE_NAME);
|
||||
|
||||
try( final Writer writer = new BufferedWriter( new OutputStreamWriter( new FileOutputStream( file ), Charset.forName( "UTF-8" ) ) ) )
|
||||
{
|
||||
FileUtils.forceMkdir( this.exportDirectory );
|
||||
try (final Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8))) {
|
||||
FileUtils.forceMkdir(this.exportDirectory);
|
||||
|
||||
final String header = this.mode == ExportMode.MINIMAL ? MINIMAL_HEADER : VERBOSE_HEADER;
|
||||
writer.write( header );
|
||||
writer.write( "\n" );
|
||||
writer.write( joined );
|
||||
writer.flush();
|
||||
final String header = this.mode == ExportMode.MINIMAL ? MINIMAL_HEADER : VERBOSE_HEADER;
|
||||
writer.write(header);
|
||||
writer.write("\n");
|
||||
writer.write(joined);
|
||||
writer.flush();
|
||||
|
||||
AELog.info( EXPORT_SUCCESSFUL_MESSAGE, lines.size(), ITEM_CSV_FILE_NAME );
|
||||
}
|
||||
catch( final IOException e )
|
||||
{
|
||||
AELog.warn( EXPORT_UNSUCCESSFUL_MESSAGE );
|
||||
AELog.debug( e );
|
||||
}
|
||||
}
|
||||
AELog.info(EXPORT_SUCCESSFUL_MESSAGE, lines.size(), ITEM_CSV_FILE_NAME);
|
||||
} catch (final IOException e) {
|
||||
AELog.warn(EXPORT_UNSUCCESSFUL_MESSAGE);
|
||||
AELog.debug(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts item name with meta and the display name
|
||||
*/
|
||||
private static final class TypeExtractFunction implements Function<ItemStack, String>
|
||||
{
|
||||
private static final String EXTRACTING_NULL_MESSAGE = "extracting type null";
|
||||
private static final String EXTRACTING_ITEM_MESSAGE = "extracting type %s:%d";
|
||||
/**
|
||||
* Extracts item name with meta and the display name
|
||||
*/
|
||||
private static final class TypeExtractFunction implements Function<ItemStack, String> {
|
||||
private static final String EXTRACTING_NULL_MESSAGE = "extracting type null";
|
||||
private static final String EXTRACTING_ITEM_MESSAGE = "extracting type %s:%d";
|
||||
|
||||
@Nonnull
|
||||
private final String itemName;
|
||||
@Nonnull
|
||||
private final ExportMode mode;
|
||||
@Nonnull
|
||||
private final String itemName;
|
||||
@Nonnull
|
||||
private final ExportMode mode;
|
||||
|
||||
private TypeExtractFunction( @Nonnull final String itemName, @Nonnull final ExportMode mode )
|
||||
{
|
||||
this.itemName = Preconditions.checkNotNull( itemName );
|
||||
Preconditions.checkArgument( !itemName.isEmpty() );
|
||||
private TypeExtractFunction(@Nonnull final String itemName, @Nonnull final ExportMode mode) {
|
||||
this.itemName = Preconditions.checkNotNull(itemName);
|
||||
Preconditions.checkArgument(!itemName.isEmpty());
|
||||
|
||||
this.mode = Preconditions.checkNotNull( mode );
|
||||
}
|
||||
this.mode = Preconditions.checkNotNull(mode);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String apply( @Nullable final ItemStack input )
|
||||
{
|
||||
if( input == null )
|
||||
{
|
||||
AELog.debug( EXTRACTING_NULL_MESSAGE );
|
||||
@Nullable
|
||||
@Override
|
||||
public String apply(@Nullable final ItemStack input) {
|
||||
if (input == null) {
|
||||
AELog.debug(EXTRACTING_NULL_MESSAGE);
|
||||
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
AELog.debug( EXTRACTING_ITEM_MESSAGE, input.getDisplayName(), input.getItemDamage() );
|
||||
}
|
||||
return null;
|
||||
} else {
|
||||
AELog.debug(EXTRACTING_ITEM_MESSAGE, input.getDisplayName(), input.getItemDamage());
|
||||
}
|
||||
|
||||
final List<String> joinedBlockAttributes = Lists.newArrayListWithCapacity( 5 );
|
||||
final int meta = input.getItemDamage();
|
||||
final String metaName = this.itemName + ':' + meta;
|
||||
final String localization = input.getDisplayName();
|
||||
final List<String> joinedBlockAttributes = Lists.newArrayListWithCapacity(5);
|
||||
final int meta = input.getItemDamage();
|
||||
final String metaName = this.itemName + ':' + meta;
|
||||
final String localization = input.getDisplayName();
|
||||
|
||||
joinedBlockAttributes.add( metaName );
|
||||
joinedBlockAttributes.add( localization );
|
||||
joinedBlockAttributes.add(metaName);
|
||||
joinedBlockAttributes.add(localization);
|
||||
|
||||
if( this.mode == ExportMode.VERBOSE )
|
||||
{
|
||||
final Item item = input.getItem();
|
||||
final String unlocalizedItem = input.getUnlocalizedName();
|
||||
final Block block = Block.getBlockFromItem( item );
|
||||
final boolean isBlock = block != Blocks.AIR && !block.equals( Blocks.AIR );
|
||||
final Class<? extends ItemStack> stackClass = input.getClass();
|
||||
final String stackClassName = stackClass.getName();
|
||||
if (this.mode == ExportMode.VERBOSE) {
|
||||
final Item item = input.getItem();
|
||||
final String unlocalizedItem = input.getUnlocalizedName();
|
||||
final Block block = Block.getBlockFromItem(item);
|
||||
final boolean isBlock = block != Blocks.AIR && !block.equals(Blocks.AIR);
|
||||
final Class<? extends ItemStack> stackClass = input.getClass();
|
||||
final String stackClassName = stackClass.getName();
|
||||
|
||||
joinedBlockAttributes.add( unlocalizedItem );
|
||||
joinedBlockAttributes.add( Boolean.toString( isBlock ) );
|
||||
joinedBlockAttributes.add( stackClassName );
|
||||
}
|
||||
joinedBlockAttributes.add(unlocalizedItem);
|
||||
joinedBlockAttributes.add(Boolean.toString(isBlock));
|
||||
joinedBlockAttributes.add(stackClassName);
|
||||
}
|
||||
|
||||
final Joiner csvJoiner = Joiner.on( ", " );
|
||||
final Joiner csvJoinerIgnoringNulls = csvJoiner.skipNulls();
|
||||
final Joiner csvJoiner = Joiner.on(", ");
|
||||
final Joiner csvJoinerIgnoringNulls = csvJoiner.skipNulls();
|
||||
|
||||
return csvJoinerIgnoringNulls.join( joinedBlockAttributes );
|
||||
}
|
||||
}
|
||||
return csvJoinerIgnoringNulls.join(joinedBlockAttributes);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* transforms an item into a row representation of the CSV file
|
||||
*/
|
||||
private static final class ItemRowExtractFunction implements Function<Item, String>
|
||||
{
|
||||
/**
|
||||
* this extension is required to apply the {@link I18n}
|
||||
*/
|
||||
private static final String LOCALIZATION_NAME_EXTENSION = ".name";
|
||||
private static final String EXPORTING_NOTHING_MESSAGE = "Exporting nothing";
|
||||
private static final String EXPORTING_SUBTYPES_MESSAGE = "Exporting input %s with subtypes: %b";
|
||||
private static final String EXPORTING_SUBTYPES_FAILED_MESSAGE = "Could not export subtypes of: %s";
|
||||
/**
|
||||
* transforms an item into a row representation of the CSV file
|
||||
*/
|
||||
private static final class ItemRowExtractFunction implements Function<Item, String> {
|
||||
/**
|
||||
* this extension is required to apply the {@link I18n}
|
||||
*/
|
||||
private static final String LOCALIZATION_NAME_EXTENSION = ".name";
|
||||
private static final String EXPORTING_NOTHING_MESSAGE = "Exporting nothing";
|
||||
private static final String EXPORTING_SUBTYPES_MESSAGE = "Exporting input %s with subtypes: %b";
|
||||
private static final String EXPORTING_SUBTYPES_FAILED_MESSAGE = "Could not export subtypes of: %s";
|
||||
|
||||
@Nonnull
|
||||
private final IForgeRegistry<Item> itemRegistry;
|
||||
@Nonnull
|
||||
private final ExportMode mode;
|
||||
@Nonnull
|
||||
private final IForgeRegistry<Item> itemRegistry;
|
||||
@Nonnull
|
||||
private final ExportMode mode;
|
||||
|
||||
/**
|
||||
* @param itemRegistry used to retrieve the name of the item
|
||||
* @param mode extracts more or less information from item depending on mode
|
||||
*/
|
||||
ItemRowExtractFunction( @Nonnull final IForgeRegistry<Item> itemRegistry, @Nonnull final ExportMode mode )
|
||||
{
|
||||
this.itemRegistry = Preconditions.checkNotNull( itemRegistry );
|
||||
this.mode = Preconditions.checkNotNull( mode );
|
||||
}
|
||||
/**
|
||||
* @param itemRegistry used to retrieve the name of the item
|
||||
* @param mode extracts more or less information from item depending on mode
|
||||
*/
|
||||
ItemRowExtractFunction(@Nonnull final IForgeRegistry<Item> itemRegistry, @Nonnull final ExportMode mode) {
|
||||
this.itemRegistry = Preconditions.checkNotNull(itemRegistry);
|
||||
this.mode = Preconditions.checkNotNull(mode);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String apply( @Nullable final Item input )
|
||||
{
|
||||
if( input == null )
|
||||
{
|
||||
AELog.debug( EXPORTING_NOTHING_MESSAGE );
|
||||
@Nullable
|
||||
@Override
|
||||
public String apply(@Nullable final Item input) {
|
||||
if (input == null) {
|
||||
AELog.debug(EXPORTING_NOTHING_MESSAGE);
|
||||
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
AELog.debug( EXPORTING_SUBTYPES_MESSAGE, input.getUnlocalizedName(), input.getHasSubtypes() );
|
||||
}
|
||||
return null;
|
||||
} else {
|
||||
AELog.debug(EXPORTING_SUBTYPES_MESSAGE, input.getUnlocalizedName(), input.getHasSubtypes());
|
||||
}
|
||||
|
||||
final String itemName = ForgeRegistries.ITEMS.getKey( input ).toString();
|
||||
final boolean hasSubtypes = input.getHasSubtypes();
|
||||
if( hasSubtypes )
|
||||
{
|
||||
final CreativeTabs creativeTab = input.getCreativeTab();
|
||||
final NonNullList<ItemStack> stacks = NonNullList.create();
|
||||
final String itemName = ForgeRegistries.ITEMS.getKey(input).toString();
|
||||
final boolean hasSubtypes = input.getHasSubtypes();
|
||||
if (hasSubtypes) {
|
||||
final CreativeTabs creativeTab = input.getCreativeTab();
|
||||
final NonNullList<ItemStack> stacks = NonNullList.create();
|
||||
|
||||
// modifies the stacks list and adds the different sub types to it
|
||||
try
|
||||
{
|
||||
input.getSubItems( creativeTab, stacks );
|
||||
}
|
||||
catch( final Exception ignored )
|
||||
{
|
||||
AELog.warn( EXPORTING_SUBTYPES_FAILED_MESSAGE, input.getUnlocalizedName() );
|
||||
AELog.debug( ignored );
|
||||
// modifies the stacks list and adds the different sub types to it
|
||||
try {
|
||||
input.getSubItems(creativeTab, stacks);
|
||||
} catch (final Exception ignored) {
|
||||
AELog.warn(EXPORTING_SUBTYPES_FAILED_MESSAGE, input.getUnlocalizedName());
|
||||
AELog.debug(ignored);
|
||||
|
||||
// ignore if mods do bullshit in their code
|
||||
return null;
|
||||
}
|
||||
// ignore if mods do bullshit in their code
|
||||
return null;
|
||||
}
|
||||
|
||||
// list can be empty, no clue why
|
||||
if( stacks.isEmpty() )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
// list can be empty, no clue why
|
||||
if (stacks.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final Joiner newLineJoiner = Joiner.on( '\n' );
|
||||
final Joiner typeJoiner = newLineJoiner.skipNulls();
|
||||
final List<String> transformedTypes = Lists.transform( stacks, new TypeExtractFunction( itemName, this.mode ) );
|
||||
final Joiner newLineJoiner = Joiner.on('\n');
|
||||
final Joiner typeJoiner = newLineJoiner.skipNulls();
|
||||
final List<String> transformedTypes = Lists.transform(stacks, new TypeExtractFunction(itemName, this.mode));
|
||||
|
||||
return typeJoiner.join( transformedTypes );
|
||||
}
|
||||
return typeJoiner.join(transformedTypes);
|
||||
}
|
||||
|
||||
final List<String> joinedBlockAttributes = Lists.newArrayListWithCapacity( 5 );
|
||||
final String unlocalizedItem = input.getUnlocalizedName();
|
||||
final String localization = I18n.translateToLocal( unlocalizedItem + LOCALIZATION_NAME_EXTENSION );
|
||||
final List<String> joinedBlockAttributes = Lists.newArrayListWithCapacity(5);
|
||||
final String unlocalizedItem = input.getUnlocalizedName();
|
||||
final String localization = I18n.translateToLocal(unlocalizedItem + LOCALIZATION_NAME_EXTENSION);
|
||||
|
||||
joinedBlockAttributes.add( itemName );
|
||||
joinedBlockAttributes.add( localization );
|
||||
joinedBlockAttributes.add(itemName);
|
||||
joinedBlockAttributes.add(localization);
|
||||
|
||||
if( this.mode == ExportMode.VERBOSE )
|
||||
{
|
||||
final Block block = Block.getBlockFromItem( input );
|
||||
final boolean isBlock = block != Blocks.AIR && !block.equals( Blocks.AIR );
|
||||
final Class<? extends Item> itemClass = input.getClass();
|
||||
final String itemClassName = itemClass.getName();
|
||||
if (this.mode == ExportMode.VERBOSE) {
|
||||
final Block block = Block.getBlockFromItem(input);
|
||||
final boolean isBlock = block != Blocks.AIR && !block.equals(Blocks.AIR);
|
||||
final Class<? extends Item> itemClass = input.getClass();
|
||||
final String itemClassName = itemClass.getName();
|
||||
|
||||
joinedBlockAttributes.add( unlocalizedItem );
|
||||
joinedBlockAttributes.add( Boolean.toString( isBlock ) );
|
||||
joinedBlockAttributes.add( itemClassName );
|
||||
}
|
||||
joinedBlockAttributes.add(unlocalizedItem);
|
||||
joinedBlockAttributes.add(Boolean.toString(isBlock));
|
||||
joinedBlockAttributes.add(itemClassName);
|
||||
}
|
||||
|
||||
final Joiner csvJoiner = Joiner.on( ", " );
|
||||
final Joiner csvJoinerIgnoringNulls = csvJoiner.skipNulls();
|
||||
final Joiner csvJoiner = Joiner.on(", ");
|
||||
final Joiner csvJoinerIgnoringNulls = csvJoiner.skipNulls();
|
||||
|
||||
return csvJoinerIgnoringNulls.join( joinedBlockAttributes );
|
||||
}
|
||||
}
|
||||
return csvJoinerIgnoringNulls.join(joinedBlockAttributes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,15 +19,12 @@
|
||||
package appeng.services.export;
|
||||
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
import net.minecraftforge.fml.common.ModContainer;
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
|
||||
import net.minecraftforge.fml.common.ModContainer;
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
@@ -38,58 +35,50 @@ import net.minecraftforge.fml.common.ModContainer;
|
||||
* @version rv3 - 01.09.2015
|
||||
* @since rv3 - 01.09.2015
|
||||
*/
|
||||
final class ModListChecker implements Checker<List<ModContainer>>
|
||||
{
|
||||
private final String configHashValue;
|
||||
final class ModListChecker implements Checker<List<ModContainer>> {
|
||||
private final String configHashValue;
|
||||
|
||||
@Nonnull
|
||||
private final ExportConfig config;
|
||||
@Nonnull
|
||||
private final ExportConfig config;
|
||||
|
||||
/**
|
||||
* @param config uses the config to retrieve the old hash of the mod list
|
||||
*/
|
||||
ModListChecker( @Nonnull final ExportConfig config )
|
||||
{
|
||||
this.config = Preconditions.checkNotNull( config );
|
||||
this.configHashValue = Preconditions.checkNotNull( config.getCache() );
|
||||
}
|
||||
/**
|
||||
* @param config uses the config to retrieve the old hash of the mod list
|
||||
*/
|
||||
ModListChecker(@Nonnull final ExportConfig config) {
|
||||
this.config = Preconditions.checkNotNull(config);
|
||||
this.configHashValue = Preconditions.checkNotNull(config.getCache());
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles a list of all mods and their versions to a digest which is updated, if it differs from the config. This
|
||||
* is used to elevate the need to export
|
||||
* the csv once again, if no change was detected.
|
||||
*
|
||||
* @param modContainers all mods and their versions to check if a difference exists between the current instance and
|
||||
* the previous instance
|
||||
*
|
||||
* @return CheckType.EQUAL if no change was detected
|
||||
*/
|
||||
@Nonnull
|
||||
@Override
|
||||
public CheckType isEqual( @Nonnull final List<ModContainer> modContainers )
|
||||
{
|
||||
Preconditions.checkNotNull( modContainers );
|
||||
/**
|
||||
* Compiles a list of all mods and their versions to a digest which is updated, if it differs from the config. This
|
||||
* is used to elevate the need to export
|
||||
* the csv once again, if no change was detected.
|
||||
*
|
||||
* @param modContainers all mods and their versions to check if a difference exists between the current instance and
|
||||
* the previous instance
|
||||
* @return CheckType.EQUAL if no change was detected
|
||||
*/
|
||||
@Nonnull
|
||||
@Override
|
||||
public CheckType isEqual(@Nonnull final List<ModContainer> modContainers) {
|
||||
Preconditions.checkNotNull(modContainers);
|
||||
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
|
||||
for( final ModContainer container : modContainers )
|
||||
{
|
||||
builder.append( container.getModId() );
|
||||
builder.append( container.getVersion() );
|
||||
}
|
||||
for (final ModContainer container : modContainers) {
|
||||
builder.append(container.getModId());
|
||||
builder.append(container.getVersion());
|
||||
}
|
||||
|
||||
final String allModsAndVersions = builder.toString();
|
||||
final String hex = DigestUtils.md5Hex( allModsAndVersions );
|
||||
final String allModsAndVersions = builder.toString();
|
||||
final String hex = DigestUtils.md5Hex(allModsAndVersions);
|
||||
|
||||
if( hex.equals( this.configHashValue ) )
|
||||
{
|
||||
return CheckType.EQUAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.config.setCache( hex );
|
||||
if (hex.equals(this.configHashValue)) {
|
||||
return CheckType.EQUAL;
|
||||
} else {
|
||||
this.config.setCache(hex);
|
||||
|
||||
return CheckType.UNEQUAL;
|
||||
}
|
||||
}
|
||||
return CheckType.UNEQUAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,10 +19,10 @@
|
||||
/**
|
||||
* the export package is to export all the required information for recipes into a convenient CSV file
|
||||
* often names are difficult to acquire without access to the internal names.
|
||||
*
|
||||
* <p>
|
||||
* To save from rescanning every start-up it can save a list of mods and their version
|
||||
* and if only something changed, it requires to update the CSV.
|
||||
*
|
||||
* <p>
|
||||
* There is no explicit check if it was manually tempered
|
||||
*
|
||||
* @author thatsIch
|
||||
|
||||
@@ -19,105 +19,91 @@
|
||||
package appeng.services.version;
|
||||
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
import javax.annotation.Nonnegative;
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
|
||||
/**
|
||||
* Base version of {@link Version}.
|
||||
*
|
||||
* <p>
|
||||
* Provides a unified way to test for equality and print a formatted string
|
||||
*/
|
||||
public abstract class BaseVersion implements Version
|
||||
{
|
||||
@Nonnegative
|
||||
private final int revision;
|
||||
@Nonnull
|
||||
private final Channel channel;
|
||||
@Nonnegative
|
||||
private final int build;
|
||||
public abstract class BaseVersion implements Version {
|
||||
@Nonnegative
|
||||
private final int revision;
|
||||
@Nonnull
|
||||
private final Channel channel;
|
||||
@Nonnegative
|
||||
private final int build;
|
||||
|
||||
/**
|
||||
* @param revision revision in natural number
|
||||
* @param channel channel
|
||||
* @param build build in natural number
|
||||
*
|
||||
* @throws AssertionError if assertion are enabled and revision or build are not natural numbers
|
||||
*/
|
||||
public BaseVersion( @Nonnegative final int revision, @Nonnull final Channel channel, @Nonnegative final int build )
|
||||
{
|
||||
Preconditions.checkArgument( revision >= 0 );
|
||||
Preconditions.checkNotNull( channel );
|
||||
Preconditions.checkArgument( build >= 0 );
|
||||
/**
|
||||
* @param revision revision in natural number
|
||||
* @param channel channel
|
||||
* @param build build in natural number
|
||||
* @throws AssertionError if assertion are enabled and revision or build are not natural numbers
|
||||
*/
|
||||
public BaseVersion(@Nonnegative final int revision, @Nonnull final Channel channel, @Nonnegative final int build) {
|
||||
Preconditions.checkArgument(revision >= 0);
|
||||
Preconditions.checkNotNull(channel);
|
||||
Preconditions.checkArgument(build >= 0);
|
||||
|
||||
this.revision = revision;
|
||||
this.channel = channel;
|
||||
this.build = build;
|
||||
}
|
||||
this.revision = revision;
|
||||
this.channel = channel;
|
||||
this.build = build;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int revision()
|
||||
{
|
||||
return this.revision;
|
||||
}
|
||||
@Override
|
||||
public final int revision() {
|
||||
return this.revision;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Channel channel()
|
||||
{
|
||||
return this.channel;
|
||||
}
|
||||
@Override
|
||||
public final Channel channel() {
|
||||
return this.channel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int build()
|
||||
{
|
||||
return this.build;
|
||||
}
|
||||
@Override
|
||||
public final int build() {
|
||||
return this.build;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String formatted()
|
||||
{
|
||||
return "rv" + this.revision + '-' + this.channel.name().toLowerCase() + '-' + this.build;
|
||||
}
|
||||
@Override
|
||||
public String formatted() {
|
||||
return "rv" + this.revision + '-' + this.channel.name().toLowerCase() + '-' + this.build;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int hashCode()
|
||||
{
|
||||
int result = this.revision;
|
||||
result = 31 * result + this.channel.hashCode();
|
||||
result = 31 * result + this.build;
|
||||
return result;
|
||||
}
|
||||
@Override
|
||||
public final int hashCode() {
|
||||
int result = this.revision;
|
||||
result = 31 * result + this.channel.hashCode();
|
||||
result = 31 * result + this.build;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean equals( final Object o )
|
||||
{
|
||||
if( this == o )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if( !( o instanceof Version ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public final boolean equals(final Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof Version)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final Version that = (Version) o;
|
||||
final Version that = (Version) o;
|
||||
|
||||
if( this.revision != that.revision() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if( this.build != that.build() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return this.channel == that.channel();
|
||||
}
|
||||
if (this.revision != that.revision()) {
|
||||
return false;
|
||||
}
|
||||
if (this.build != that.build()) {
|
||||
return false;
|
||||
}
|
||||
return this.channel == that.channel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String toString()
|
||||
{
|
||||
return "Version{" + "revision=" + this.revision + ", channel=" + this.channel + ", build=" + this.build + '}';
|
||||
}
|
||||
@Override
|
||||
public final String toString() {
|
||||
return "Version{" + "revision=" + this.revision + ", channel=" + this.channel + ", build=" + this.build + '}';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@ package appeng.services.version;
|
||||
* Represents the release channel of Applied Energistics. The mod is either in Alpha, Beta or Stable channel.
|
||||
* Any more might be confusing to the end-user
|
||||
*/
|
||||
public enum Channel
|
||||
{
|
||||
Alpha, Beta, Stable
|
||||
public enum Channel {
|
||||
Alpha, Beta, Stable
|
||||
}
|
||||
|
||||
@@ -27,25 +27,22 @@ import javax.annotation.Nonnull;
|
||||
* AE prints version like rv2-beta-8
|
||||
* GitHub prints version like rv2.beta.8
|
||||
*/
|
||||
public final class DefaultVersion extends BaseVersion
|
||||
{
|
||||
/**
|
||||
* @param revision natural number
|
||||
* @param channel either alpha, beta or release
|
||||
* @param build natural number
|
||||
*/
|
||||
public DefaultVersion( @Nonnegative final int revision, @Nonnull final Channel channel, @Nonnegative final int build )
|
||||
{
|
||||
super( revision, channel, build );
|
||||
}
|
||||
public final class DefaultVersion extends BaseVersion {
|
||||
/**
|
||||
* @param revision natural number
|
||||
* @param channel either alpha, beta or release
|
||||
* @param build natural number
|
||||
*/
|
||||
public DefaultVersion(@Nonnegative final int revision, @Nonnull final Channel channel, @Nonnegative final int build) {
|
||||
super(revision, channel, build);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNewerAs( final Version maybeOlder )
|
||||
{
|
||||
final boolean isNewerRevision = this.revision() > maybeOlder.revision();
|
||||
final boolean isNewerChannel = this.channel().compareTo( maybeOlder.channel() ) > 0;
|
||||
final boolean isNewerBuild = this.build() > maybeOlder.build();
|
||||
@Override
|
||||
public boolean isNewerAs(final Version maybeOlder) {
|
||||
final boolean isNewerRevision = this.revision() > maybeOlder.revision();
|
||||
final boolean isNewerChannel = this.channel().compareTo(maybeOlder.channel()) > 0;
|
||||
final boolean isNewerBuild = this.build() > maybeOlder.build();
|
||||
|
||||
return isNewerRevision || isNewerChannel || isNewerBuild;
|
||||
}
|
||||
return isNewerRevision || isNewerChannel || isNewerBuild;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,22 +22,18 @@ package appeng.services.version;
|
||||
/**
|
||||
* Exceptional template for {@link Version}, when the mod does not want a check
|
||||
*/
|
||||
public final class DoNotCheckVersion extends BaseVersion
|
||||
{
|
||||
public DoNotCheckVersion()
|
||||
{
|
||||
super( Integer.MAX_VALUE, Channel.Stable, Integer.MAX_VALUE );
|
||||
}
|
||||
public final class DoNotCheckVersion extends BaseVersion {
|
||||
public DoNotCheckVersion() {
|
||||
super(Integer.MAX_VALUE, Channel.Stable, Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNewerAs( final Version maybeOlder )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public boolean isNewerAs(final Version maybeOlder) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String formatted()
|
||||
{
|
||||
return "dev build";
|
||||
}
|
||||
@Override
|
||||
public String formatted() {
|
||||
return "dev build";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,27 +22,22 @@ package appeng.services.version;
|
||||
/**
|
||||
* Exceptional template when the {@link Version} could not be retrieved
|
||||
*/
|
||||
public final class MissingVersion extends BaseVersion
|
||||
{
|
||||
public MissingVersion()
|
||||
{
|
||||
super( 0, Channel.Alpha, 0 );
|
||||
}
|
||||
public final class MissingVersion extends BaseVersion {
|
||||
public MissingVersion() {
|
||||
super(0, Channel.Alpha, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param maybeOlder ignored
|
||||
*
|
||||
* @return false
|
||||
*/
|
||||
@Override
|
||||
public boolean isNewerAs( final Version maybeOlder )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* @param maybeOlder ignored
|
||||
* @return false
|
||||
*/
|
||||
@Override
|
||||
public boolean isNewerAs(final Version maybeOlder) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String formatted()
|
||||
{
|
||||
return "missing";
|
||||
}
|
||||
@Override
|
||||
public String formatted() {
|
||||
return "missing";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,57 +19,50 @@
|
||||
package appeng.services.version;
|
||||
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import appeng.core.AELog;
|
||||
import appeng.services.version.exceptions.VersionCheckerException;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
|
||||
/**
|
||||
* Wrapper for {@link VersionParser} to check if the check is happening in developer environment or in a pull request.
|
||||
*
|
||||
* <p>
|
||||
* In that case ignore the check.
|
||||
*/
|
||||
public final class ModVersionFetcher implements VersionFetcher
|
||||
{
|
||||
private static final Version EXCEPTIONAL_VERSION = new MissingVersion();
|
||||
public final class ModVersionFetcher implements VersionFetcher {
|
||||
private static final Version EXCEPTIONAL_VERSION = new MissingVersion();
|
||||
|
||||
@Nonnull
|
||||
private final String rawModVersion;
|
||||
@Nonnull
|
||||
private final VersionParser parser;
|
||||
@Nonnull
|
||||
private final String rawModVersion;
|
||||
@Nonnull
|
||||
private final VersionParser parser;
|
||||
|
||||
public ModVersionFetcher( @Nonnull final String rawModVersion, @Nonnull final VersionParser parser )
|
||||
{
|
||||
this.rawModVersion = rawModVersion;
|
||||
this.parser = parser;
|
||||
}
|
||||
public ModVersionFetcher(@Nonnull final String rawModVersion, @Nonnull final VersionParser parser) {
|
||||
this.rawModVersion = rawModVersion;
|
||||
this.parser = parser;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses only, if not checked in developer environment or in a pull request
|
||||
*
|
||||
* @return {@link DoNotCheckVersion} if in developer environment or pull request, {@link MissingVersion} in case of
|
||||
* a parser exception or else the parsed {@link Version}.
|
||||
*/
|
||||
@Override
|
||||
public Version get()
|
||||
{
|
||||
if( this.rawModVersion.equals( "@version@" ) || this.rawModVersion.contains( "pr" ) )
|
||||
{
|
||||
return new DoNotCheckVersion();
|
||||
}
|
||||
/**
|
||||
* Parses only, if not checked in developer environment or in a pull request
|
||||
*
|
||||
* @return {@link DoNotCheckVersion} if in developer environment or pull request, {@link MissingVersion} in case of
|
||||
* a parser exception or else the parsed {@link Version}.
|
||||
*/
|
||||
@Override
|
||||
public Version get() {
|
||||
if (this.rawModVersion.equals("@version@") || this.rawModVersion.contains("pr")) {
|
||||
return new DoNotCheckVersion();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
final Version version = this.parser.parse( this.rawModVersion );
|
||||
try {
|
||||
final Version version = this.parser.parse(this.rawModVersion);
|
||||
|
||||
return version;
|
||||
}
|
||||
catch( final VersionCheckerException e )
|
||||
{
|
||||
AELog.debug( e );
|
||||
return version;
|
||||
} catch (final VersionCheckerException e) {
|
||||
AELog.debug(e);
|
||||
|
||||
return EXCEPTIONAL_VERSION;
|
||||
}
|
||||
}
|
||||
return EXCEPTIONAL_VERSION;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,39 +22,38 @@ package appeng.services.version;
|
||||
/**
|
||||
* Stores version information, which are easily compared
|
||||
*/
|
||||
public interface Version
|
||||
{
|
||||
/**
|
||||
* @return revision of this version
|
||||
*/
|
||||
int revision();
|
||||
public interface Version {
|
||||
/**
|
||||
* @return revision of this version
|
||||
*/
|
||||
int revision();
|
||||
|
||||
/**
|
||||
* @return channel of this version
|
||||
*/
|
||||
Channel channel();
|
||||
/**
|
||||
* @return channel of this version
|
||||
*/
|
||||
Channel channel();
|
||||
|
||||
/**
|
||||
* @return build of this version
|
||||
*/
|
||||
int build();
|
||||
/**
|
||||
* @return build of this version
|
||||
*/
|
||||
int build();
|
||||
|
||||
/**
|
||||
* A version is never if these criteria are met:
|
||||
* if the current revision is higher than the compared revision OR
|
||||
* if revision are equal and the current channel is higher than the compared channel (Stable > Beta > Alpha) OR
|
||||
* if revision, channel are equal and the build is higher than the compared build
|
||||
*
|
||||
* @return true if criteria are met
|
||||
*/
|
||||
boolean isNewerAs( Version maybeOlder );
|
||||
/**
|
||||
* A version is never if these criteria are met:
|
||||
* if the current revision is higher than the compared revision OR
|
||||
* if revision are equal and the current channel is higher than the compared channel (Stable > Beta > Alpha) OR
|
||||
* if revision, channel are equal and the build is higher than the compared build
|
||||
*
|
||||
* @return true if criteria are met
|
||||
*/
|
||||
boolean isNewerAs(Version maybeOlder);
|
||||
|
||||
/**
|
||||
* Prints the revision, channel and build into a common displayed way
|
||||
*
|
||||
* rv2-beta-8
|
||||
*
|
||||
* @return formatted version
|
||||
*/
|
||||
String formatted();
|
||||
/**
|
||||
* Prints the revision, channel and build into a common displayed way
|
||||
* <p>
|
||||
* rv2-beta-8
|
||||
*
|
||||
* @return formatted version
|
||||
*/
|
||||
String formatted();
|
||||
}
|
||||
|
||||
@@ -19,116 +19,103 @@
|
||||
package appeng.services.version;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Date;
|
||||
import com.google.common.base.Preconditions;
|
||||
import net.minecraftforge.common.config.Configuration;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
import net.minecraftforge.common.config.Configuration;
|
||||
import java.io.File;
|
||||
import java.util.Date;
|
||||
|
||||
|
||||
/**
|
||||
* Separate config file to handle the version checker
|
||||
*/
|
||||
public final class VersionCheckerConfig
|
||||
{
|
||||
private static final int DEFAULT_INTERVAL_HOURS = 24;
|
||||
private static final int MIN_INTERVAL_HOURS = 0;
|
||||
private static final int MAX_INTERVAL_HOURS = 7 * 24;
|
||||
public final class VersionCheckerConfig {
|
||||
private static final int DEFAULT_INTERVAL_HOURS = 24;
|
||||
private static final int MIN_INTERVAL_HOURS = 0;
|
||||
private static final int MAX_INTERVAL_HOURS = 7 * 24;
|
||||
|
||||
@Nonnull
|
||||
private final Configuration config;
|
||||
@Nonnull
|
||||
private final Configuration config;
|
||||
|
||||
private final boolean isEnabled;
|
||||
private final boolean isEnabled;
|
||||
|
||||
@Nonnull
|
||||
private final String lastCheck;
|
||||
private final int interval;
|
||||
@Nonnull
|
||||
private final String lastCheck;
|
||||
private final int interval;
|
||||
|
||||
@Nonnull
|
||||
private final String level;
|
||||
@Nonnull
|
||||
private final String level;
|
||||
|
||||
private final boolean shouldNotifyPlayer;
|
||||
private final boolean shouldPostChangelog;
|
||||
private final boolean shouldNotifyPlayer;
|
||||
private final boolean shouldPostChangelog;
|
||||
|
||||
/**
|
||||
* @param file requires fully qualified file in which the config is saved
|
||||
*/
|
||||
public VersionCheckerConfig( @Nonnull final File file )
|
||||
{
|
||||
Preconditions.checkNotNull( file );
|
||||
Preconditions.checkState( !file.isDirectory() );
|
||||
/**
|
||||
* @param file requires fully qualified file in which the config is saved
|
||||
*/
|
||||
public VersionCheckerConfig(@Nonnull final File file) {
|
||||
Preconditions.checkNotNull(file);
|
||||
Preconditions.checkState(!file.isDirectory());
|
||||
|
||||
this.config = new Configuration( file );
|
||||
this.config = new Configuration(file);
|
||||
|
||||
// initializes default values by caching
|
||||
this.isEnabled = this.config.getBoolean( "enabled", "general", true, "If true, the version checker is enabled. Acts as a master switch." );
|
||||
// initializes default values by caching
|
||||
this.isEnabled = this.config.getBoolean("enabled", "general", true, "If true, the version checker is enabled. Acts as a master switch.");
|
||||
|
||||
this.lastCheck = this.config.getString( "lastCheck", "cache", "0",
|
||||
"The number of milliseconds since January 1, 1970, 00:00:00 GMT of the last successful check." );
|
||||
this.interval = this.config.getInt( "interval", "cache", DEFAULT_INTERVAL_HOURS, MIN_INTERVAL_HOURS, MAX_INTERVAL_HOURS,
|
||||
"Waits as many hours, until it checks again." );
|
||||
this.lastCheck = this.config.getString("lastCheck", "cache", "0",
|
||||
"The number of milliseconds since January 1, 1970, 00:00:00 GMT of the last successful check.");
|
||||
this.interval = this.config.getInt("interval", "cache", DEFAULT_INTERVAL_HOURS, MIN_INTERVAL_HOURS, MAX_INTERVAL_HOURS,
|
||||
"Waits as many hours, until it checks again.");
|
||||
|
||||
this.level = this.config.getString( "level", "channel", "Beta",
|
||||
"Determines the channel level which should be checked for updates. Can be either Stable, Beta or Alpha." );
|
||||
this.level = this.config.getString("level", "channel", "Beta",
|
||||
"Determines the channel level which should be checked for updates. Can be either Stable, Beta or Alpha.");
|
||||
|
||||
this.shouldNotifyPlayer = this.config.getBoolean( "notify", "client", true,
|
||||
"If true, the player is getting a notification, that a new version is available." );
|
||||
this.shouldPostChangelog = this.config.getBoolean( "changelog", "client", true,
|
||||
"If true, the player is getting a notification including changelog. Only happens if notification are enabled." );
|
||||
}
|
||||
this.shouldNotifyPlayer = this.config.getBoolean("notify", "client", true,
|
||||
"If true, the player is getting a notification, that a new version is available.");
|
||||
this.shouldPostChangelog = this.config.getBoolean("changelog", "client", true,
|
||||
"If true, the player is getting a notification including changelog. Only happens if notification are enabled.");
|
||||
}
|
||||
|
||||
public boolean isVersionCheckingEnabled()
|
||||
{
|
||||
return this.isEnabled;
|
||||
}
|
||||
public boolean isVersionCheckingEnabled() {
|
||||
return this.isEnabled;
|
||||
}
|
||||
|
||||
public String lastCheck()
|
||||
{
|
||||
return this.lastCheck;
|
||||
}
|
||||
public String lastCheck() {
|
||||
return this.lastCheck;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the current date in milli seconds into the "lastCheck" field of the config and makes it persistent.
|
||||
*/
|
||||
public void updateLastCheck()
|
||||
{
|
||||
final Date now = new Date();
|
||||
final long nowInMs = now.getTime();
|
||||
final String nowAsString = Long.toString( nowInMs );
|
||||
/**
|
||||
* Stores the current date in milli seconds into the "lastCheck" field of the config and makes it persistent.
|
||||
*/
|
||||
public void updateLastCheck() {
|
||||
final Date now = new Date();
|
||||
final long nowInMs = now.getTime();
|
||||
final String nowAsString = Long.toString(nowInMs);
|
||||
|
||||
this.config.get( "cache", "lastCheck", "0" ).set( nowAsString );
|
||||
this.config.get("cache", "lastCheck", "0").set(nowAsString);
|
||||
|
||||
this.config.save();
|
||||
}
|
||||
this.config.save();
|
||||
}
|
||||
|
||||
public int interval()
|
||||
{
|
||||
return this.interval;
|
||||
}
|
||||
public int interval() {
|
||||
return this.interval;
|
||||
}
|
||||
|
||||
public String level()
|
||||
{
|
||||
return this.level;
|
||||
}
|
||||
public String level() {
|
||||
return this.level;
|
||||
}
|
||||
|
||||
public boolean shouldNotifyPlayer()
|
||||
{
|
||||
return this.shouldNotifyPlayer;
|
||||
}
|
||||
public boolean shouldNotifyPlayer() {
|
||||
return this.shouldNotifyPlayer;
|
||||
}
|
||||
|
||||
public boolean shouldPostChangelog()
|
||||
{
|
||||
return this.shouldPostChangelog;
|
||||
}
|
||||
public boolean shouldPostChangelog() {
|
||||
return this.shouldPostChangelog;
|
||||
}
|
||||
|
||||
public void save()
|
||||
{
|
||||
if( this.config.hasChanged() )
|
||||
{
|
||||
this.config.save();
|
||||
}
|
||||
}
|
||||
public void save() {
|
||||
if (this.config.hasChanged()) {
|
||||
this.config.save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@ package appeng.services.version;
|
||||
/**
|
||||
* Processes base information to retrieve a {@link Version}
|
||||
*/
|
||||
public interface VersionFetcher
|
||||
{
|
||||
Version get();
|
||||
public interface VersionFetcher {
|
||||
Version get();
|
||||
}
|
||||
|
||||
@@ -19,182 +19,148 @@
|
||||
package appeng.services.version;
|
||||
|
||||
|
||||
import java.util.Scanner;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import appeng.services.version.exceptions.*;
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
import appeng.services.version.exceptions.InvalidBuildException;
|
||||
import appeng.services.version.exceptions.InvalidChannelException;
|
||||
import appeng.services.version.exceptions.InvalidRevisionException;
|
||||
import appeng.services.version.exceptions.InvalidVersionException;
|
||||
import appeng.services.version.exceptions.MissingSeparatorException;
|
||||
import appeng.services.version.exceptions.VersionCheckerException;
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.Scanner;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
||||
/**
|
||||
* can parse a version in form of rv2-beta-8 or rv2.beta.8
|
||||
*/
|
||||
public final class VersionParser
|
||||
{
|
||||
private static final Pattern PATTERN_DOT = Pattern.compile( "\\." );
|
||||
private static final Pattern PATTERN_DASH = Pattern.compile( "-" );
|
||||
private static final Pattern PATTERN_REVISION = Pattern.compile( "[^0-9]+" );
|
||||
private static final Pattern PATTERN_BUILD = Pattern.compile( "[^0-9]+" );
|
||||
private static final Pattern PATTERN_NATURAL = Pattern.compile( "[0-9]+" );
|
||||
private static final Pattern PATTERN_VALID_REVISION = Pattern.compile( "^rv\\d+$" );
|
||||
public final class VersionParser {
|
||||
private static final Pattern PATTERN_DOT = Pattern.compile("\\.");
|
||||
private static final Pattern PATTERN_DASH = Pattern.compile("-");
|
||||
private static final Pattern PATTERN_REVISION = Pattern.compile("[^0-9]+");
|
||||
private static final Pattern PATTERN_BUILD = Pattern.compile("[^0-9]+");
|
||||
private static final Pattern PATTERN_NATURAL = Pattern.compile("[0-9]+");
|
||||
private static final Pattern PATTERN_VALID_REVISION = Pattern.compile("^rv\\d+$");
|
||||
|
||||
/**
|
||||
* Parses the {@link Version} out of a String
|
||||
*
|
||||
* @param raw String in form of rv2-beta-8 or rv2.beta.8
|
||||
*
|
||||
* @return {@link Version} encoded in the raw String
|
||||
*
|
||||
* @throws VersionCheckerException if parsing the raw string was not successful.
|
||||
*
|
||||
*/
|
||||
public Version parse( @Nonnull final String raw ) throws VersionCheckerException
|
||||
{
|
||||
Preconditions.checkNotNull( raw );
|
||||
/**
|
||||
* Parses the {@link Version} out of a String
|
||||
*
|
||||
* @param raw String in form of rv2-beta-8 or rv2.beta.8
|
||||
* @return {@link Version} encoded in the raw String
|
||||
* @throws VersionCheckerException if parsing the raw string was not successful.
|
||||
*/
|
||||
public Version parse(@Nonnull final String raw) throws VersionCheckerException {
|
||||
Preconditions.checkNotNull(raw);
|
||||
|
||||
final String transformed = this.transformDelimiter( raw );
|
||||
final String[] split = transformed.split( "_" );
|
||||
final String transformed = this.transformDelimiter(raw);
|
||||
final String[] split = transformed.split("_");
|
||||
|
||||
return this.parseVersion( split );
|
||||
}
|
||||
return this.parseVersion(split);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces all "." and "-" into "_" to make them uniform
|
||||
*
|
||||
* @param raw raw version string containing "." or "-"
|
||||
*
|
||||
* @return transformed raw, where "." and "-" are replaced by "_"
|
||||
*
|
||||
* @throws MissingSeparatorException if not containing valid separators
|
||||
*/
|
||||
private String transformDelimiter( @Nonnull final String raw ) throws MissingSeparatorException
|
||||
{
|
||||
if( !( raw.contains( "." ) || raw.contains( "-" ) ) )
|
||||
{
|
||||
throw new MissingSeparatorException();
|
||||
}
|
||||
/**
|
||||
* Replaces all "." and "-" into "_" to make them uniform
|
||||
*
|
||||
* @param raw raw version string containing "." or "-"
|
||||
* @return transformed raw, where "." and "-" are replaced by "_"
|
||||
* @throws MissingSeparatorException if not containing valid separators
|
||||
*/
|
||||
private String transformDelimiter(@Nonnull final String raw) throws MissingSeparatorException {
|
||||
if (!(raw.contains(".") || raw.contains("-"))) {
|
||||
throw new MissingSeparatorException();
|
||||
}
|
||||
|
||||
final String withoutDot = PATTERN_DOT.matcher( raw ).replaceAll( "_" );
|
||||
final String withoutDash = PATTERN_DASH.matcher( withoutDot ).replaceAll( "_" );
|
||||
final String withoutDot = PATTERN_DOT.matcher(raw).replaceAll("_");
|
||||
final String withoutDash = PATTERN_DASH.matcher(withoutDot).replaceAll("_");
|
||||
|
||||
return withoutDash;
|
||||
}
|
||||
return withoutDash;
|
||||
}
|
||||
|
||||
/**
|
||||
* parses the {@link Version} out of the split.
|
||||
* The split must have a length of 3,
|
||||
* representing revision, channel and build.
|
||||
*
|
||||
* @param splitRaw raw version split with length of 3
|
||||
*
|
||||
* @return {@link Version} represented by the splitRaw
|
||||
*
|
||||
* @throws InvalidVersionException when length not 3
|
||||
* @throws InvalidRevisionException {@link VersionParser#parseRevision(String)}
|
||||
* @throws InvalidChannelException {@link VersionParser#parseChannel(String)}
|
||||
* @throws InvalidBuildException {@link VersionParser#parseBuild(String)}
|
||||
*/
|
||||
private Version parseVersion( @Nonnull final String[] splitRaw ) throws InvalidVersionException, InvalidRevisionException, InvalidChannelException, InvalidBuildException
|
||||
{
|
||||
if( splitRaw.length != 3 )
|
||||
{
|
||||
throw new InvalidVersionException();
|
||||
}
|
||||
/**
|
||||
* parses the {@link Version} out of the split.
|
||||
* The split must have a length of 3,
|
||||
* representing revision, channel and build.
|
||||
*
|
||||
* @param splitRaw raw version split with length of 3
|
||||
* @return {@link Version} represented by the splitRaw
|
||||
* @throws InvalidVersionException when length not 3
|
||||
* @throws InvalidRevisionException {@link VersionParser#parseRevision(String)}
|
||||
* @throws InvalidChannelException {@link VersionParser#parseChannel(String)}
|
||||
* @throws InvalidBuildException {@link VersionParser#parseBuild(String)}
|
||||
*/
|
||||
private Version parseVersion(@Nonnull final String[] splitRaw) throws InvalidVersionException, InvalidRevisionException, InvalidChannelException, InvalidBuildException {
|
||||
if (splitRaw.length != 3) {
|
||||
throw new InvalidVersionException();
|
||||
}
|
||||
|
||||
final String rawRevision = splitRaw[0];
|
||||
final String rawChannel = splitRaw[1];
|
||||
final String rawBuild = splitRaw[2];
|
||||
final String rawRevision = splitRaw[0];
|
||||
final String rawChannel = splitRaw[1];
|
||||
final String rawBuild = splitRaw[2];
|
||||
|
||||
final int revision = this.parseRevision( rawRevision );
|
||||
final Channel channel = this.parseChannel( rawChannel );
|
||||
final int build = this.parseBuild( rawBuild );
|
||||
final int revision = this.parseRevision(rawRevision);
|
||||
final Channel channel = this.parseChannel(rawChannel);
|
||||
final int build = this.parseBuild(rawBuild);
|
||||
|
||||
return new DefaultVersion( revision, channel, build );
|
||||
}
|
||||
return new DefaultVersion(revision, channel, build);
|
||||
}
|
||||
|
||||
/**
|
||||
* A revision starts with the keyword "rv", followed by a natural number
|
||||
*
|
||||
* @param rawRevision String containing the revision number
|
||||
*
|
||||
* @return revision number
|
||||
*
|
||||
* @throws InvalidRevisionException if not matching "rv" followed by a natural number.
|
||||
*/
|
||||
private int parseRevision( @Nonnull final String rawRevision ) throws InvalidRevisionException
|
||||
{
|
||||
if( !PATTERN_VALID_REVISION.matcher( rawRevision ).matches() )
|
||||
{
|
||||
throw new InvalidRevisionException();
|
||||
}
|
||||
/**
|
||||
* A revision starts with the keyword "rv", followed by a natural number
|
||||
*
|
||||
* @param rawRevision String containing the revision number
|
||||
* @return revision number
|
||||
* @throws InvalidRevisionException if not matching "rv" followed by a natural number.
|
||||
*/
|
||||
private int parseRevision(@Nonnull final String rawRevision) throws InvalidRevisionException {
|
||||
if (!PATTERN_VALID_REVISION.matcher(rawRevision).matches()) {
|
||||
throw new InvalidRevisionException();
|
||||
}
|
||||
|
||||
final Scanner scanner = new Scanner( rawRevision );
|
||||
final Scanner scanner = new Scanner(rawRevision);
|
||||
|
||||
final int revision = scanner.useDelimiter( PATTERN_REVISION ).nextInt();
|
||||
final int revision = scanner.useDelimiter(PATTERN_REVISION).nextInt();
|
||||
|
||||
scanner.close();
|
||||
scanner.close();
|
||||
|
||||
return revision;
|
||||
}
|
||||
return revision;
|
||||
}
|
||||
|
||||
/**
|
||||
* A channel is atm either one of {@link Channel#Alpha}, {@link Channel#Beta} or {@link Channel#Stable}
|
||||
*
|
||||
* @param rawChannel String containing the channel
|
||||
*
|
||||
* @return matching {@link Channel} to the String
|
||||
*
|
||||
* @throws InvalidChannelException if not one of {@link Channel} values.
|
||||
*/
|
||||
private Channel parseChannel( @Nonnull final String rawChannel ) throws InvalidChannelException
|
||||
{
|
||||
if( !( rawChannel.equalsIgnoreCase( Channel.Alpha.name() ) || rawChannel.equalsIgnoreCase( Channel.Beta.name() ) || rawChannel
|
||||
.equalsIgnoreCase( Channel.Stable.name() ) ) )
|
||||
{
|
||||
throw new InvalidChannelException();
|
||||
}
|
||||
/**
|
||||
* A channel is atm either one of {@link Channel#Alpha}, {@link Channel#Beta} or {@link Channel#Stable}
|
||||
*
|
||||
* @param rawChannel String containing the channel
|
||||
* @return matching {@link Channel} to the String
|
||||
* @throws InvalidChannelException if not one of {@link Channel} values.
|
||||
*/
|
||||
private Channel parseChannel(@Nonnull final String rawChannel) throws InvalidChannelException {
|
||||
if (!(rawChannel.equalsIgnoreCase(Channel.Alpha.name()) || rawChannel.equalsIgnoreCase(Channel.Beta.name()) || rawChannel
|
||||
.equalsIgnoreCase(Channel.Stable.name()))) {
|
||||
throw new InvalidChannelException();
|
||||
}
|
||||
|
||||
for( final Channel channel : Channel.values() )
|
||||
{
|
||||
if( channel.name().equalsIgnoreCase( rawChannel ) )
|
||||
{
|
||||
return channel;
|
||||
}
|
||||
}
|
||||
for (final Channel channel : Channel.values()) {
|
||||
if (channel.name().equalsIgnoreCase(rawChannel)) {
|
||||
return channel;
|
||||
}
|
||||
}
|
||||
|
||||
throw new InvalidChannelException();
|
||||
}
|
||||
throw new InvalidChannelException();
|
||||
}
|
||||
|
||||
/**
|
||||
* A build is just a natural number
|
||||
*
|
||||
* @param rawBuild String containing the build number
|
||||
*
|
||||
* @return build number
|
||||
*
|
||||
* @throws InvalidBuildException if not a natural number.
|
||||
*/
|
||||
private int parseBuild( @Nonnull final String rawBuild ) throws InvalidBuildException
|
||||
{
|
||||
if( !PATTERN_NATURAL.matcher( rawBuild ).matches() )
|
||||
{
|
||||
throw new InvalidBuildException();
|
||||
}
|
||||
/**
|
||||
* A build is just a natural number
|
||||
*
|
||||
* @param rawBuild String containing the build number
|
||||
* @return build number
|
||||
* @throws InvalidBuildException if not a natural number.
|
||||
*/
|
||||
private int parseBuild(@Nonnull final String rawBuild) throws InvalidBuildException {
|
||||
if (!PATTERN_NATURAL.matcher(rawBuild).matches()) {
|
||||
throw new InvalidBuildException();
|
||||
}
|
||||
|
||||
final Scanner scanner = new Scanner( rawBuild );
|
||||
final Scanner scanner = new Scanner(rawBuild);
|
||||
|
||||
final int build = scanner.useDelimiter( PATTERN_BUILD ).nextInt();
|
||||
final int build = scanner.useDelimiter(PATTERN_BUILD).nextInt();
|
||||
|
||||
scanner.close();
|
||||
scanner.close();
|
||||
|
||||
return build;
|
||||
}
|
||||
return build;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,12 +22,10 @@ package appeng.services.version.exceptions;
|
||||
/**
|
||||
* Indicates a invalid build number, which is any string except a natural number.
|
||||
*/
|
||||
public class InvalidBuildException extends VersionCheckerException
|
||||
{
|
||||
private static final long serialVersionUID = 3015432444672364991L;
|
||||
public class InvalidBuildException extends VersionCheckerException {
|
||||
private static final long serialVersionUID = 3015432444672364991L;
|
||||
|
||||
public InvalidBuildException()
|
||||
{
|
||||
super( "Invalid Build: Needs to be a natural number." );
|
||||
}
|
||||
public InvalidBuildException() {
|
||||
super("Invalid Build: Needs to be a natural number.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,12 +25,10 @@ import appeng.services.version.Channel;
|
||||
/**
|
||||
* Indicates an invalid {@link Channel} value.
|
||||
*/
|
||||
public class InvalidChannelException extends VersionCheckerException
|
||||
{
|
||||
private static final long serialVersionUID = -1306378515002341620L;
|
||||
public class InvalidChannelException extends VersionCheckerException {
|
||||
private static final long serialVersionUID = -1306378515002341620L;
|
||||
|
||||
public InvalidChannelException()
|
||||
{
|
||||
super( "Invalid Channel: Needs to be one of the following values; alpha, beta, or stable." );
|
||||
}
|
||||
public InvalidChannelException() {
|
||||
super("Invalid Channel: Needs to be one of the following values; alpha, beta, or stable.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,13 +22,11 @@ package appeng.services.version.exceptions;
|
||||
/**
|
||||
* Indicates a invalid revision, which does not match the pattern "rv" followed by a natural number.
|
||||
*/
|
||||
public class InvalidRevisionException extends VersionCheckerException
|
||||
{
|
||||
public class InvalidRevisionException extends VersionCheckerException {
|
||||
|
||||
private static final long serialVersionUID = 4828906902143875942L;
|
||||
private static final long serialVersionUID = 4828906902143875942L;
|
||||
|
||||
public InvalidRevisionException()
|
||||
{
|
||||
super( "Invalid Revision: Needs to be 'rv' followd by a natural number." );
|
||||
}
|
||||
public InvalidRevisionException() {
|
||||
super("Invalid Revision: Needs to be 'rv' followd by a natural number.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,13 +22,11 @@ package appeng.services.version.exceptions;
|
||||
/**
|
||||
* Indicates an invalid version, which does not consists of 3 parts matching /(rv\d+)-(alpha|beta|stable)-(b\d+)/.
|
||||
*/
|
||||
public class InvalidVersionException extends VersionCheckerException
|
||||
{
|
||||
public class InvalidVersionException extends VersionCheckerException {
|
||||
|
||||
private static final long serialVersionUID = 4828906902143875942L;
|
||||
private static final long serialVersionUID = 4828906902143875942L;
|
||||
|
||||
public InvalidVersionException()
|
||||
{
|
||||
super( "Invalid Version Format: Need to consist of exactly 3 parts separated by a dash." );
|
||||
}
|
||||
public InvalidVersionException() {
|
||||
super("Invalid Version Format: Need to consist of exactly 3 parts separated by a dash.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,15 +21,13 @@ package appeng.services.version.exceptions;
|
||||
|
||||
/**
|
||||
* Indicates a version without a valid separator.
|
||||
*
|
||||
* <p>
|
||||
* Valid separators are a dash ("-") or dot (".")
|
||||
*/
|
||||
public class MissingSeparatorException extends VersionCheckerException
|
||||
{
|
||||
private static final long serialVersionUID = 8366370192017020750L;
|
||||
public class MissingSeparatorException extends VersionCheckerException {
|
||||
private static final long serialVersionUID = 8366370192017020750L;
|
||||
|
||||
public MissingSeparatorException()
|
||||
{
|
||||
super( "Invalid Revision: Needs to match 'rv' followed by a natural number." );
|
||||
}
|
||||
public MissingSeparatorException() {
|
||||
super("Invalid Revision: Needs to match 'rv' followed by a natural number.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,12 +25,10 @@ import javax.annotation.Nonnull;
|
||||
/**
|
||||
* A super class for any exception thrown by the version checker for easier handling.
|
||||
*/
|
||||
public class VersionCheckerException extends Exception
|
||||
{
|
||||
private static final long serialVersionUID = 4582501864800542884L;
|
||||
public class VersionCheckerException extends Exception {
|
||||
private static final long serialVersionUID = 4582501864800542884L;
|
||||
|
||||
public VersionCheckerException( @Nonnull final String string )
|
||||
{
|
||||
super( string );
|
||||
}
|
||||
public VersionCheckerException(@Nonnull final String string) {
|
||||
super(string);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,36 +19,32 @@
|
||||
package appeng.services.version.github;
|
||||
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import appeng.services.version.Version;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
|
||||
/**
|
||||
* Default template when a {@link FormattedRelease} is needed.
|
||||
*/
|
||||
public final class DefaultFormattedRelease implements FormattedRelease
|
||||
{
|
||||
@Nonnull
|
||||
private final Version version;
|
||||
@Nonnull
|
||||
private final String changelog;
|
||||
public final class DefaultFormattedRelease implements FormattedRelease {
|
||||
@Nonnull
|
||||
private final Version version;
|
||||
@Nonnull
|
||||
private final String changelog;
|
||||
|
||||
public DefaultFormattedRelease( @Nonnull final Version version, @Nonnull final String changelog )
|
||||
{
|
||||
this.version = version;
|
||||
this.changelog = changelog;
|
||||
}
|
||||
public DefaultFormattedRelease(@Nonnull final Version version, @Nonnull final String changelog) {
|
||||
this.version = version;
|
||||
this.changelog = changelog;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String changelog()
|
||||
{
|
||||
return this.changelog;
|
||||
}
|
||||
@Override
|
||||
public String changelog() {
|
||||
return this.changelog;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Version version()
|
||||
{
|
||||
return this.version;
|
||||
}
|
||||
@Override
|
||||
public Version version() {
|
||||
return this.version;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,15 +25,14 @@ import appeng.services.version.Version;
|
||||
/**
|
||||
* Represents the acquired, processed information through github about a release of Applied Energistics 2
|
||||
*/
|
||||
public interface FormattedRelease
|
||||
{
|
||||
/**
|
||||
* @return changelog
|
||||
*/
|
||||
String changelog();
|
||||
public interface FormattedRelease {
|
||||
/**
|
||||
* @return changelog
|
||||
*/
|
||||
String changelog();
|
||||
|
||||
/**
|
||||
* @return processed version
|
||||
*/
|
||||
Version version();
|
||||
/**
|
||||
* @return processed version
|
||||
*/
|
||||
Version version();
|
||||
}
|
||||
|
||||
@@ -19,40 +19,36 @@
|
||||
package appeng.services.version.github;
|
||||
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import appeng.services.version.MissingVersion;
|
||||
import appeng.services.version.Version;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
|
||||
/**
|
||||
* Exceptional template, when no meaningful {@link FormattedRelease} could be obtained
|
||||
*/
|
||||
public final class MissingFormattedRelease implements FormattedRelease
|
||||
{
|
||||
@Nonnull
|
||||
private final Version version;
|
||||
public final class MissingFormattedRelease implements FormattedRelease {
|
||||
@Nonnull
|
||||
private final Version version;
|
||||
|
||||
public MissingFormattedRelease()
|
||||
{
|
||||
this.version = new MissingVersion();
|
||||
}
|
||||
public MissingFormattedRelease() {
|
||||
this.version = new MissingVersion();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return empty string
|
||||
*/
|
||||
@Override
|
||||
public String changelog()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
/**
|
||||
* @return empty string
|
||||
*/
|
||||
@Override
|
||||
public String changelog() {
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@link MissingVersion}
|
||||
*/
|
||||
@Override
|
||||
public Version version()
|
||||
{
|
||||
return this.version;
|
||||
}
|
||||
/**
|
||||
* @return {@link MissingVersion}
|
||||
*/
|
||||
@Override
|
||||
public Version version() {
|
||||
return this.version;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,16 +22,15 @@ package appeng.services.version.github;
|
||||
/**
|
||||
* Template class for Gson to write values from the Json Object into an actual class
|
||||
*/
|
||||
@SuppressWarnings( "all" )
|
||||
public class Release
|
||||
{
|
||||
/**
|
||||
* name of the tag it is saved
|
||||
*/
|
||||
public String tag_name;
|
||||
@SuppressWarnings("all")
|
||||
public class Release {
|
||||
/**
|
||||
* name of the tag it is saved
|
||||
*/
|
||||
public String tag_name;
|
||||
|
||||
/**
|
||||
* Contains the changelog
|
||||
*/
|
||||
public String body;
|
||||
/**
|
||||
* Contains the changelog
|
||||
*/
|
||||
public String body;
|
||||
}
|
||||
|
||||
@@ -19,104 +19,86 @@
|
||||
package appeng.services.version.github;
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Type;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
import appeng.core.AELog;
|
||||
import appeng.services.version.Channel;
|
||||
import appeng.services.version.Version;
|
||||
import appeng.services.version.VersionCheckerConfig;
|
||||
import appeng.services.version.VersionParser;
|
||||
import appeng.services.version.exceptions.VersionCheckerException;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Type;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public final class ReleaseFetcher
|
||||
{
|
||||
private static final String GITHUB_RELEASES_URL = "https://api.github.com/repos/AppliedEnergistics/Applied-Energistics-2/releases";
|
||||
private static final FormattedRelease EXCEPTIONAL_RELEASE = new MissingFormattedRelease();
|
||||
public final class ReleaseFetcher {
|
||||
private static final String GITHUB_RELEASES_URL = "https://api.github.com/repos/AppliedEnergistics/Applied-Energistics-2/releases";
|
||||
private static final FormattedRelease EXCEPTIONAL_RELEASE = new MissingFormattedRelease();
|
||||
|
||||
@Nonnull
|
||||
private final VersionCheckerConfig config;
|
||||
@Nonnull
|
||||
private final VersionParser parser;
|
||||
@Nonnull
|
||||
private final VersionCheckerConfig config;
|
||||
@Nonnull
|
||||
private final VersionParser parser;
|
||||
|
||||
public ReleaseFetcher( @Nonnull final VersionCheckerConfig config, @Nonnull final VersionParser parser )
|
||||
{
|
||||
this.config = config;
|
||||
this.parser = parser;
|
||||
}
|
||||
public ReleaseFetcher(@Nonnull final VersionCheckerConfig config, @Nonnull final VersionParser parser) {
|
||||
this.config = config;
|
||||
this.parser = parser;
|
||||
}
|
||||
|
||||
public FormattedRelease get()
|
||||
{
|
||||
final Gson gson = new Gson();
|
||||
final Type type = new ReleasesTypeToken().getType();
|
||||
public FormattedRelease get() {
|
||||
final Gson gson = new Gson();
|
||||
final Type type = new ReleasesTypeToken().getType();
|
||||
|
||||
try
|
||||
{
|
||||
final URL releasesURL = new URL( GITHUB_RELEASES_URL );
|
||||
final String rawReleases = this.getRawReleases( releasesURL );
|
||||
try {
|
||||
final URL releasesURL = new URL(GITHUB_RELEASES_URL);
|
||||
final String rawReleases = this.getRawReleases(releasesURL);
|
||||
|
||||
this.config.updateLastCheck();
|
||||
this.config.updateLastCheck();
|
||||
|
||||
final List<Release> releases = gson.fromJson( rawReleases, type );
|
||||
final FormattedRelease latestFitRelease = this.getLatestFitRelease( releases );
|
||||
final List<Release> releases = gson.fromJson(rawReleases, type);
|
||||
final FormattedRelease latestFitRelease = this.getLatestFitRelease(releases);
|
||||
|
||||
return latestFitRelease;
|
||||
}
|
||||
catch( final VersionCheckerException e )
|
||||
{
|
||||
AELog.debug( e );
|
||||
}
|
||||
catch( final MalformedURLException e )
|
||||
{
|
||||
AELog.debug( e );
|
||||
}
|
||||
catch( final IOException e )
|
||||
{
|
||||
AELog.debug( e );
|
||||
}
|
||||
return latestFitRelease;
|
||||
} catch (final VersionCheckerException e) {
|
||||
AELog.debug(e);
|
||||
} catch (final MalformedURLException e) {
|
||||
AELog.debug(e);
|
||||
} catch (final IOException e) {
|
||||
AELog.debug(e);
|
||||
}
|
||||
|
||||
return EXCEPTIONAL_RELEASE;
|
||||
}
|
||||
return EXCEPTIONAL_RELEASE;
|
||||
}
|
||||
|
||||
private String getRawReleases( final URL url ) throws IOException
|
||||
{
|
||||
return IOUtils.toString( url );
|
||||
}
|
||||
private String getRawReleases(final URL url) throws IOException {
|
||||
return IOUtils.toString(url);
|
||||
}
|
||||
|
||||
private FormattedRelease getLatestFitRelease( final Iterable<Release> releases ) throws VersionCheckerException
|
||||
{
|
||||
final String levelInConfig = this.config.level();
|
||||
final Channel level = Channel.valueOf( levelInConfig );
|
||||
final int levelOrdinal = level.ordinal();
|
||||
private FormattedRelease getLatestFitRelease(final Iterable<Release> releases) throws VersionCheckerException {
|
||||
final String levelInConfig = this.config.level();
|
||||
final Channel level = Channel.valueOf(levelInConfig);
|
||||
final int levelOrdinal = level.ordinal();
|
||||
|
||||
for( final Release release : releases )
|
||||
{
|
||||
final String rawVersion = release.tag_name;
|
||||
final String changelog = release.body;
|
||||
for (final Release release : releases) {
|
||||
final String rawVersion = release.tag_name;
|
||||
final String changelog = release.body;
|
||||
|
||||
final Version version = this.parser.parse( rawVersion );
|
||||
final Version version = this.parser.parse(rawVersion);
|
||||
|
||||
if( version.channel().ordinal() >= levelOrdinal )
|
||||
{
|
||||
return new DefaultFormattedRelease( version, changelog );
|
||||
}
|
||||
}
|
||||
if (version.channel().ordinal() >= levelOrdinal) {
|
||||
return new DefaultFormattedRelease(version, changelog);
|
||||
}
|
||||
}
|
||||
|
||||
return EXCEPTIONAL_RELEASE;
|
||||
}
|
||||
return EXCEPTIONAL_RELEASE;
|
||||
}
|
||||
|
||||
private static final class ReleasesTypeToken extends TypeToken<List<Release>>
|
||||
{
|
||||
}
|
||||
private static final class ReleasesTypeToken extends TypeToken<List<Release>> {
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user