mirror of
https://github.com/2006-Scape/apollo.git
synced 2026-07-03 00:38:21 +00:00
Verify CRCs on login,
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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(...)}.
|
||||
*
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user