Verify CRCs on login,

This commit is contained in:
atomicint
2015-04-13 13:59:44 -04:00
parent 7a12a27c76
commit aba1dffa0e
6 changed files with 70 additions and 20 deletions
+4 -4
View File
@@ -122,8 +122,9 @@ public final class Server {
public void init(String releaseClassName) throws Exception {
Class<?> clazz = Class.forName(releaseClassName);
Release release = (Release) clazz.newInstance();
int releaseNo = release.getReleaseNumber();
logger.info("Initialized release #" + release.getReleaseNumber() + ".");
logger.info("Initialized release #" + releaseNo + ".");
serviceBootstrap.group(loopGroup);
httpBootstrap.group(loopGroup);
@@ -131,7 +132,8 @@ public final class Server {
World world = new World();
ServiceManager serviceManager = new ServiceManager(world);
ServerContext context = new ServerContext(release, serviceManager);
IndexedFileSystem fs = new IndexedFileSystem(Paths.get("data/fs", Integer.toString(releaseNo)), true);
ServerContext context = new ServerContext(release, serviceManager, fs);
ApolloHandler handler = new ApolloHandler(context);
ChannelInitializer<SocketChannel> serviceInitializer = new ServiceChannelInitializer(handler);
@@ -149,8 +151,6 @@ public final class Server {
PluginManager manager = new PluginManager(world, new PluginContext(context));
serviceManager.startAll();
int releaseNo = release.getReleaseNumber();
IndexedFileSystem fs = new IndexedFileSystem(Paths.get("data/fs", Integer.toString(releaseNo)), true);
world.init(releaseNo, fs, manager);
}
+17 -1
View File
@@ -1,5 +1,6 @@
package org.apollo;
import org.apollo.fs.IndexedFileSystem;
import org.apollo.net.release.Release;
/**
@@ -21,16 +22,22 @@ public final class ServerContext {
*/
private final ServiceManager serviceManager;
/**
* The IndexedFileSystem.
*/
private final IndexedFileSystem fileSystem;
/**
* Creates a new server context.
*
* @param release The current release.
* @param serviceManager The service manager.
*/
ServerContext(Release release, ServiceManager serviceManager) {
ServerContext(Release release, ServiceManager serviceManager, IndexedFileSystem fileSystem) {
this.release = release;
this.serviceManager = serviceManager;
this.serviceManager.setContext(this);
this.fileSystem = fileSystem;
}
/**
@@ -42,6 +49,15 @@ public final class ServerContext {
return release;
}
/**
* Gets the IndexeFileSystem
*
* @return The IndexedFileSystem.
*/
public IndexedFileSystem getFileSystem() {
return fileSystem;
}
/**
* Gets a service. This method is shorthand for {@code getServiceManager().getService(...)}.
*
+42 -11
View File
@@ -3,6 +3,8 @@ package org.apollo.login;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@@ -16,12 +18,11 @@ import org.apollo.net.codec.login.LoginRequest;
import org.apollo.net.release.Release;
import org.apollo.net.session.GameSession;
import org.apollo.net.session.LoginSession;
import org.apollo.util.ThreadUtil;
import org.apollo.util.xml.XmlNode;
import org.apollo.util.xml.XmlParser;
import org.xml.sax.SAXException;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
/**
* The {@link LoginService} manages {@link LoginRequest}s.
*
@@ -33,7 +34,7 @@ public final class LoginService extends Service {
/**
* The {@link ExecutorService} to which workers are submitted.
*/
private final ExecutorService executor = Executors.newCachedThreadPool(new ThreadFactoryBuilder().setNameFormat("LoginService").build());
private final ExecutorService executor = Executors.newCachedThreadPool(ThreadUtil.build("LoginService"));
/**
* The current {@link PlayerSerializer}.
@@ -79,9 +80,6 @@ public final class LoginService extends Service {
this.serializer = (PlayerSerializer) clazz.getConstructor(World.class).newInstance(world);
}
/**
* Starts the login service.
*/
@Override
public void start() {
@@ -92,15 +90,48 @@ public final class LoginService extends Service {
*
* @param session The session submitting this request.
* @param request The login request.
* @throws IOException If some I/O exception occurs.
*/
public void submitLoadRequest(LoginSession session, LoginRequest request) {
public void submitLoadRequest(LoginSession session, LoginRequest request) throws IOException {
int response = LoginConstants.STATUS_OK;
if (requiresUpdate(session, request)) {
response = LoginConstants.STATUS_GAME_UPDATED;
}
if (response == LoginConstants.STATUS_OK) {
executor.submit(new PlayerLoaderWorker(serializer, session, request));
} else {
session.handlePlayerLoaderResponse(request, new PlayerLoaderResponse(response));
}
}
/**
* Checks if an update is required whenever a {@link Player} submits a login request.
*
* @param session The login session.
* @param request The login request.
* @return {@code true} if an update is required, otherwise return {@code false}.
* @throws IOException If some I/O exception occurs.
*/
private boolean requiresUpdate(LoginSession session, LoginRequest request) throws IOException {
Release release = session.getRelease();
if (release.getReleaseNumber() != request.getReleaseNumber()) {
// TODO check archive 0 CRCs
session.handlePlayerLoaderResponse(request, new PlayerLoaderResponse(LoginConstants.STATUS_GAME_UPDATED));
} else {
executor.submit(new PlayerLoaderWorker(serializer, session, request));
return true;
}
ByteBuffer buffer = getContext().getFileSystem().getCrcTable();
int[] clientCrcs = request.getArchiveCrcs();
int[] serverCrcs = new int[clientCrcs.length];
Arrays.setAll(serverCrcs, crc -> buffer.getInt());
if (Arrays.equals(clientCrcs, serverCrcs)) {
return false;
}
return true;
}
/**
+1 -1
View File
@@ -66,7 +66,7 @@ public final class ApolloHandler extends ChannelInboundHandlerAdapter {
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object message) {
public void channelRead(ChannelHandlerContext ctx, Object message) throws Exception {
try {
Attribute<Session> attribute = ctx.attr(NetworkConstants.SESSION_KEY);
Session session = attribute.get();
+4 -2
View File
@@ -5,6 +5,7 @@ import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import java.io.IOException;
import java.util.Optional;
import org.apollo.ServerContext;
@@ -72,8 +73,9 @@ public final class LoginSession extends Session {
* Handles a login request.
*
* @param request The login request.
* @throws IOException If some I/O exception occurs.
*/
private void handleLoginRequest(LoginRequest request) {
private void handleLoginRequest(LoginRequest request) throws IOException {
LoginService loginService = serverContext.getService(LoginService.class);
loginService.submitLoadRequest(this, request);
}
@@ -135,7 +137,7 @@ public final class LoginSession extends Session {
}
@Override
public void messageReceived(Object message) {
public void messageReceived(Object message) throws Exception {
if (message.getClass() == LoginRequest.class) {
handleLoginRequest((LoginRequest) message);
}
+2 -1
View File
@@ -42,7 +42,8 @@ public abstract class Session {
* Processes a message received from the channel.
*
* @param message The message.
* @throws Exception If some error occurs.
*/
public abstract void messageReceived(Object message);
public abstract void messageReceived(Object message) throws Exception;
}