Make cache client a little more friendly to use

This commit is contained in:
Adam
2017-03-11 21:23:15 -05:00
parent 693452a0a7
commit 9170c41856
3 changed files with 82 additions and 52 deletions

View File

@@ -22,7 +22,6 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.runelite.cache.downloader;
import com.google.common.base.Stopwatch;
@@ -44,7 +43,9 @@ import java.util.ArrayDeque;
import java.util.Queue;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import net.runelite.cache.downloader.requests.ConnectionInfo;
import net.runelite.cache.downloader.requests.FileRequest;
import net.runelite.cache.downloader.requests.HelloHandshake;
import net.runelite.cache.fs.Archive;
import net.runelite.cache.fs.Index;
import net.runelite.cache.fs.Store;
@@ -58,14 +59,17 @@ public class CacheClient
private static final String HOST = "oldschool1.runescape.com";
private static final int PORT = 43594;
private static final int CLIENT_REVISION = 135;
private static final int CLIENT_REVISION = 138;
private Store store; // store cache will be written to
private int clientRevision;
private final Store store; // store cache will be written to
private final int clientRevision;
private ClientState state;
private EventLoopGroup group = new NioEventLoopGroup(1);
private Channel channel;
private CompletableFuture<Integer> handshakeFuture;
private Queue<PendingFileRequest> requests = new ArrayDeque<>();
public CacheClient(Store store)
@@ -101,7 +105,52 @@ public class CacheClient
channel = f.channel();
}
public void stop()
public CompletableFuture<Integer> handshake()
{
HelloHandshake msg = new HelloHandshake();
msg.setRevision(getClientRevision());
ByteBuf message = Unpooled.buffer(5);
message.writeByte(msg.getType()); // handshake type
message.writeInt(msg.getRevision()); // client revision
state = ClientState.HANDSHAKING;
channel.writeAndFlush(message);
logger.info("Sent handshake with revision {}", msg.getRevision());
assert handshakeFuture == null;
handshakeFuture = new CompletableFuture<>();
return handshakeFuture;
}
public void onHandshake(int response)
{
assert handshakeFuture != null;
handshakeFuture.complete(response);
if (response != HelloHandshake.RESPONSE_OK)
{
close();
return;
}
// Send connection info
ConnectionInfo cinfo = new ConnectionInfo();
ByteBuf outbuf = Unpooled.buffer(4);
outbuf.writeByte(cinfo.getType());
outbuf.writeMedium(cinfo.getPadding());
channel.writeAndFlush(outbuf);
state = ClientState.CONNECTED;
logger.info("Client is now connected!");
}
public void close()
{
channel.close().syncUninterruptibly();
group.shutdownGracefully();
@@ -112,13 +161,18 @@ public class CacheClient
return clientRevision;
}
public ClientState getState()
{
return state;
}
public void download() throws InterruptedException, ExecutionException, FileNotFoundException, IOException
{
Stopwatch stopwatch = Stopwatch.createStarted();
FileResult result = requestFile(255, 255).get();
result.decompress(null);
ByteBuf buffer = Unpooled.wrappedBuffer(result.getContents());
int indexCount = result.getContents().length / 8;
@@ -211,6 +265,11 @@ public class CacheClient
public synchronized CompletableFuture<FileResult> requestFile(int index, int fileId)
{
if (state != ClientState.CONNECTED)
{
throw new IllegalStateException("Can't request files until connected!");
}
ByteBuf buf = Unpooled.buffer(4);
FileRequest request = new FileRequest(index, fileId);
CompletableFuture<FileResult> future = new CompletableFuture<>();

View File

@@ -30,7 +30,6 @@ import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.ReferenceCountUtil;
import net.runelite.cache.downloader.requests.ConnectionInfo;
import net.runelite.cache.downloader.requests.HelloHandshake;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -39,38 +38,22 @@ public class CacheClientHandler extends ChannelInboundHandlerAdapter
{
private static final Logger logger = LoggerFactory.getLogger(CacheClientHandler.class);
private CacheClient client;
private ClientState state;
private ByteBuf buffer = Unpooled.buffer(512);
private final CacheClient client;
private final ByteBuf buffer = Unpooled.buffer(512);
public CacheClientHandler(CacheClient client)
{
this.client = client;
}
@Override
public void channelActive(ChannelHandlerContext ctx)
{
HelloHandshake msg = new HelloHandshake();
msg.setRevision(client.getClientRevision());
ByteBuf message = Unpooled.buffer(5);
message.writeByte(msg.getType()); // handshake type
message.writeInt(msg.getRevision()); // client revision
ctx.writeAndFlush(message);
logger.info("Sent handshake with revision {}", msg.getRevision());
state = ClientState.HANDSHAKING;
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg)
{
ByteBuf inbuf = (ByteBuf) msg;
buffer.writeBytes(inbuf);
ClientState state = client.getState();
if (state == ClientState.HANDSHAKING)
{
int response = buffer.readByte();
@@ -83,18 +66,9 @@ public class CacheClientHandler extends ChannelInboundHandlerAdapter
logger.warn("Client version is outdated");
else
logger.warn("Handshake response error {}", response);
ctx.close();
return;
}
ConnectionInfo cinfo = new ConnectionInfo();
ByteBuf outbuf = Unpooled.buffer(4);
outbuf.writeByte(cinfo.getType());
outbuf.writeMedium(cinfo.getPadding());
ctx.writeAndFlush(outbuf);
state = ClientState.CONNECTED;
client.onHandshake(response);
}
else if (state == ClientState.CONNECTED)
{
@@ -210,7 +184,7 @@ public class CacheClientHandler extends ChannelInboundHandlerAdapter
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
{
// Close the connection when an exception is raised.
cause.printStackTrace();
logger.warn(null, cause);
ctx.close();
}
}

View File

@@ -22,18 +22,23 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.runelite.cache.downloader;
import java.io.File;
import java.util.concurrent.CompletableFuture;
import net.runelite.cache.fs.Store;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.impl.SimpleLogger;
public class CacheClientTest
{
private static final Logger logger = LoggerFactory.getLogger(CacheClientTest.class);
@Before
public void before()
{
@@ -49,24 +54,16 @@ public class CacheClientTest
CacheClient c = new CacheClient(store);
c.connect();
CompletableFuture<Integer> handshake = c.handshake();
// c.requestFile(0, 205).get();
// c.requestFile(3, 278).get();
// c.requestFile(3, 127).get();
// c.requestFile(0, 1210).get();
Integer result = handshake.get();
logger.info("Handshake result: {}", result);
// c.requestFile(255, 255).get();
// c.requestFile(255, 2).get();
// c.requestFile(4, 2047);
// c.requestFile(6, 546);
// c.requestFile(255, 6).get();
Assert.assertEquals(0, (int) result);
c.download();
c.stop();
c.close();
store.save();
}