Merge PlayerSaver and PlayerLoader into PlayerSerializer.

This commit is contained in:
Major-
2015-03-03 07:25:20 +00:00
parent 1859276a22
commit 65ecd1b5fc
18 changed files with 300 additions and 350 deletions
+1 -2
View File
@@ -1,4 +1,3 @@
<login>
<loader>org.apollo.io.player.impl.DummyPlayerLoader</loader>
<saver>org.apollo.io.player.impl.DiscardPlayerSaver</saver>
<serializer>org.apollo.io.player.DummyPlayerSerializer</serializer>
</login>
@@ -0,0 +1,56 @@
package org.apollo.io.player;
import java.io.File;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.apollo.util.NameUtil;
/**
* A utility class with common functionality used by the binary player loader/ savers.
*
* @author Graham
* @author Major
*/
public final class BinaryFileUtils {
/**
* The Path to the saved games directory.
*/
private static final Path SAVED_GAMES_DIRECTORY = Paths.get("data/savedGames");
/**
* Creates the saved games directory if it does not exist.
*/
static {
try {
if (!Files.exists(SAVED_GAMES_DIRECTORY)) {
Files.createDirectory(SAVED_GAMES_DIRECTORY);
}
} catch (IOException e) {
throw new UncheckedIOException("Error creating saved games directory.", e);
}
}
/**
* Gets the save {@link File} for the specified player.
*
* @param username The username of the player.
* @return The file.
*/
public static Path getFile(String username) {
String filtered = NameUtil.decodeBase37(NameUtil.encodeBase37(username));
return SAVED_GAMES_DIRECTORY.resolve(filtered + ".dat");
}
/**
* Sole private constructor to prevent instantiation.
*/
private BinaryFileUtils() {
}
}
@@ -1,13 +1,20 @@
package org.apollo.io.player.impl;
package org.apollo.io.player;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.apollo.game.model.Appearance;
import org.apollo.game.model.Item;
@@ -16,6 +23,8 @@ import org.apollo.game.model.entity.Player;
import org.apollo.game.model.entity.Skill;
import org.apollo.game.model.entity.SkillSet;
import org.apollo.game.model.entity.attr.Attribute;
import org.apollo.game.model.entity.attr.AttributeMap;
import org.apollo.game.model.entity.attr.AttributePersistence;
import org.apollo.game.model.entity.attr.AttributeType;
import org.apollo.game.model.entity.attr.BooleanAttribute;
import org.apollo.game.model.entity.attr.NumericalAttribute;
@@ -26,8 +35,6 @@ import org.apollo.game.model.entity.setting.PrivacyState;
import org.apollo.game.model.entity.setting.PrivilegeLevel;
import org.apollo.game.model.entity.setting.ScreenBrightness;
import org.apollo.game.model.inv.Inventory;
import org.apollo.io.player.PlayerLoader;
import org.apollo.io.player.PlayerLoaderResponse;
import org.apollo.net.codec.login.LoginConstants;
import org.apollo.security.PlayerCredentials;
import org.apollo.util.NameUtil;
@@ -36,28 +43,39 @@ import org.apollo.util.StreamUtil;
import com.lambdaworks.crypto.SCryptUtil;
/**
* A {@link PlayerLoader} implementation that loads data from a binary file.
* A {@link PlayerSerializer} implementation that uses a binary file to store player data.
*
* @author Graham
* @author Major
*/
public final class BinaryPlayerLoader implements PlayerLoader {
public final class BinaryPlayerSerializer implements PlayerSerializer {
/**
* The default spawn position.
* The Path to the saved games directory.
*/
private static final Position SPAWN_POSITION = new Position(3093, 3104);
private static final Path SAVED_GAMES_DIRECTORY = Paths.get("data/savedGames");
static {
try {
if (!Files.exists(SAVED_GAMES_DIRECTORY)) {
Files.createDirectory(SAVED_GAMES_DIRECTORY);
}
} catch (IOException e) {
throw new UncheckedIOException("Error creating saved games directory.", e);
}
}
@Override
public PlayerLoaderResponse loadPlayer(PlayerCredentials credentials) throws IOException {
File file = BinaryPlayerUtil.getFile(credentials.getUsername());
if (!file.exists()) {
Player player = new Player(credentials, SPAWN_POSITION);
player.getBank().add(995, 25); // 25 coins
Path path = getFile(credentials.getUsername());
if (!Files.exists(path)) {
Player player = new Player(credentials, TUTORIAL_ISLAND_SPAWN);
credentials.setPassword(SCryptUtil.scrypt(credentials.getPassword(), 16384, 8, 1));
return new PlayerLoaderResponse(LoginConstants.STATUS_OK, player);
}
try (DataInputStream in = new DataInputStream(new FileInputStream(file))) {
try (DataInputStream in = new DataInputStream(new BufferedInputStream(Files.newInputStream(path)))) {
String name = StreamUtil.readString(in);
String password = StreamUtil.readString(in);
@@ -67,37 +85,35 @@ public final class BinaryPlayerLoader implements PlayerLoader {
credentials.setPassword(password); // Update password to the hashed one.
PrivilegeLevel privilegeLevel = PrivilegeLevel.valueOf(in.readByte());
PrivilegeLevel privilege = PrivilegeLevel.valueOf(in.readByte());
MembershipStatus members = MembershipStatus.valueOf(in.readByte());
PrivacyState chatPrivacy = PrivacyState.valueOf(in.readByte(), true);
PrivacyState friendPrivacy = PrivacyState.valueOf(in.readByte(), false);
PrivacyState tradePrivacy = PrivacyState.valueOf(in.readByte(), false);
int runEnergy = in.readByte();
ScreenBrightness brightness = ScreenBrightness.valueOf(in.readByte());
int x = in.readUnsignedShort();
int y = in.readUnsignedShort();
int height = in.readUnsignedByte();
int genderIntValue = in.readUnsignedByte();
Gender gender = genderIntValue == Gender.MALE.toInteger() ? Gender.MALE : Gender.FEMALE;
Gender gender = (in.readUnsignedByte() == Gender.MALE.toInteger()) ? Gender.MALE : Gender.FEMALE;
int[] style = new int[7];
for (int i = 0; i < style.length; i++) {
style[i] = in.readUnsignedByte();
for (int slot = 0; slot < style.length; slot++) {
style[slot] = in.readUnsignedByte();
}
int[] colors = new int[5];
for (int i = 0; i < colors.length; i++) {
colors[i] = in.readUnsignedByte();
for (int slot = 0; slot < colors.length; slot++) {
colors[slot] = in.readUnsignedByte();
}
Player player = new Player(credentials, new Position(x, y, height));
player.setPrivilegeLevel(privilegeLevel);
player.setPrivilegeLevel(privilege);
player.setMembers(members);
player.setChatPrivacy(chatPrivacy);
player.setFriendPrivacy(friendPrivacy);
player.setTradePrivacy(tradePrivacy);
player.setRunEnergy(runEnergy);
player.setScreenBrightness(brightness);
player.setAppearance(new Appearance(gender, style, colors));
@@ -141,6 +157,87 @@ public final class BinaryPlayerLoader implements PlayerLoader {
}
}
@Override
public void savePlayer(Player player) throws IOException {
Path file = getFile(player.getUsername());
try (DataOutputStream out = new DataOutputStream(Files.newOutputStream(file))) {
StreamUtil.writeString(out, player.getUsername());
StreamUtil.writeString(out, player.getCredentials().getPassword());
out.writeByte(player.getPrivilegeLevel().toInteger());
out.writeByte(player.getMembershipStatus().getValue());
out.writeByte(player.getChatPrivacy().toInteger(true));
out.writeByte(player.getFriendPrivacy().toInteger(false));
out.writeByte(player.getTradePrivacy().toInteger(false));
out.writeByte(player.getScreenBrightness().toInteger());
Position position = player.getPosition();
out.writeShort(position.getX());
out.writeShort(position.getY());
out.writeByte(position.getHeight());
Appearance appearance = player.getAppearance();
out.writeByte(appearance.getGender().toInteger());
int[] style = appearance.getStyle();
for (int element : style) {
out.writeByte(element);
}
int[] colors = appearance.getColors();
for (int color : colors) {
out.writeByte(color);
}
writeInventory(out, player.getInventory());
writeInventory(out, player.getEquipment());
writeInventory(out, player.getBank());
SkillSet skills = player.getSkillSet();
out.writeByte(skills.size());
for (int id = 0; id < skills.size(); id++) {
Skill skill = skills.getSkill(id);
out.writeByte(skill.getCurrentLevel());
out.writeDouble(skill.getExperience());
}
List<String> usernames = player.getFriendUsernames();
out.writeByte(usernames.size());
for (String username : usernames) {
out.writeLong(NameUtil.encodeBase37(username));
}
usernames = player.getIgnoredUsernames();
out.writeByte(usernames.size());
for (String username : usernames) {
out.writeLong(NameUtil.encodeBase37(username));
}
Set<Entry<String, Attribute<?>>> attributes = player.getAttributes().entrySet();
attributes.removeIf(e -> AttributeMap.getDefinition(e.getKey()).getPersistence() != AttributePersistence.PERSISTENT);
out.writeInt(attributes.size());
for (Entry<String, Attribute<?>> entry : attributes) {
String name = entry.getKey();
StreamUtil.writeString(out, name);
Attribute<?> attribute = entry.getValue();
out.writeByte(attribute.getType().getValue());
out.write(attribute.encode());
}
}
}
/**
* Gets the save {@link File} for the specified player.
*
* @param username The username of the player.
* @return The file.
*/
private Path getFile(String username) {
String filtered = NameUtil.decodeBase37(NameUtil.encodeBase37(username));
return SAVED_GAMES_DIRECTORY.resolve(filtered + ".dat");
}
/**
* Reads the player's {@link Attribute}s.
*
@@ -148,7 +245,7 @@ public final class BinaryPlayerLoader implements PlayerLoader {
* @return The {@link Map} of attribute names to attributes.
* @throws IOException If there is an error reading from the stream.
*/
private static Map<String, Attribute<?>> readAttributes(DataInputStream in) throws IOException {
private Map<String, Attribute<?>> readAttributes(DataInputStream in) throws IOException {
int count = in.readInt();
Map<String, Attribute<?>> attributes = new HashMap<>(count);
@@ -187,7 +284,7 @@ public final class BinaryPlayerLoader implements PlayerLoader {
* @param inventory The inventory.
* @throws IOException If an I/O error occurs.
*/
private static void readInventory(DataInputStream in, Inventory inventory) throws IOException {
private void readInventory(DataInputStream in, Inventory inventory) throws IOException {
int capacity = in.readUnsignedShort();
inventory.stopFiringEvents();
@@ -206,4 +303,27 @@ public final class BinaryPlayerLoader implements PlayerLoader {
}
}
/**
* Writes an inventory to the specified output stream.
*
* @param out The output stream.
* @param inventory The inventory.
* @throws IOException If an I/O error occurs.
*/
private void writeInventory(DataOutputStream out, Inventory inventory) throws IOException {
int capacity = inventory.capacity();
out.writeShort(capacity);
for (int slot = 0; slot < capacity; slot++) {
Item item = inventory.get(slot);
if (item != null) {
out.writeShort(item.getId() + 1);
out.writeInt(item.getAmount());
} else {
out.writeShort(0);
out.writeInt(0);
}
}
}
}
@@ -1,35 +1,33 @@
package org.apollo.io.player.impl;
package org.apollo.io.player;
import org.apollo.game.model.Position;
import org.apollo.game.model.entity.Player;
import org.apollo.game.model.entity.setting.MembershipStatus;
import org.apollo.game.model.entity.setting.PrivilegeLevel;
import org.apollo.io.player.PlayerLoader;
import org.apollo.io.player.PlayerLoaderResponse;
import org.apollo.net.codec.login.LoginConstants;
import org.apollo.security.PlayerCredentials;
/**
* A dummy {@link PlayerLoader} implementation used for testing purposes.
* A {@link PlayerSerializer} that saves no data and returns an administrator member account, ideal for debugging.
*
* @author Graham
* @author Major
*/
public final class DummyPlayerLoader implements PlayerLoader {
/**
* The default spawn position for players loaded by this loader.
*/
private static final Position DEFAULT_POSITION = new Position(3093, 3104);
public final class DummyPlayerSerializer implements PlayerSerializer {
@Override
public PlayerLoaderResponse loadPlayer(PlayerCredentials credentials) {
int status = LoginConstants.STATUS_OK;
Player player = new Player(credentials, DEFAULT_POSITION);
Player player = new Player(credentials, TUTORIAL_ISLAND_SPAWN);
player.setPrivilegeLevel(PrivilegeLevel.ADMINISTRATOR);
player.setMembers(MembershipStatus.PAID);
return new PlayerLoaderResponse(status, player);
}
@Override
public void savePlayer(Player player) {
/* discard player */
}
}
@@ -0,0 +1,23 @@
package org.apollo.io.player;
import org.apollo.game.model.entity.Player;
import org.apollo.security.PlayerCredentials;
/**
* A {@link PlayerSerializer} that utilises {@code JDBC} to communicate with an SQL database containing player data.
*
* @author Major
*/
public final class JdbcPlayerSerializer implements PlayerSerializer {
@Override
public void savePlayer(Player player) throws Exception {
throw new UnsupportedOperationException("JDBC saving is not supported at this time.");
}
@Override
public PlayerLoaderResponse loadPlayer(PlayerCredentials credentials) throws Exception {
throw new UnsupportedOperationException("JDBC loading is not supported at this time.");
}
}
@@ -1,22 +0,0 @@
package org.apollo.io.player;
import org.apollo.security.PlayerCredentials;
/**
* An interface which may be extended by others which are capable of loading players. For example, implementations might
* include text-based, binary and SQL loaders.
*
* @author Graham
*/
public interface PlayerLoader {
/**
* Loads a player.
*
* @param credentials The player's credentials.
* @return The {@link PlayerLoaderResponse}.
* @throws Exception If an error occurs.
*/
public PlayerLoaderResponse loadPlayer(PlayerCredentials credentials) throws Exception;
}
@@ -8,9 +8,10 @@ import org.apollo.net.codec.login.LoginConstants;
import com.google.common.base.Preconditions;
/**
* A response for the {@link PlayerLoader#loadPlayer(org.apollo.security.PlayerCredentials)} call.
* A response for the {@link PlayerSerializer#loadPlayer} call.
*
* @author Graham
* @author Major
*/
public final class PlayerLoaderResponse {
@@ -32,7 +33,8 @@ public final class PlayerLoaderResponse {
* {@link LoginConstants#STATUS_RECONNECTION_OK}.
*/
public PlayerLoaderResponse(int status) {
Preconditions.checkArgument(status != LoginConstants.STATUS_OK && status != LoginConstants.STATUS_RECONNECTION_OK, "Player required for this status code.");
Preconditions.checkArgument(status != LoginConstants.STATUS_OK && status != LoginConstants.STATUS_RECONNECTION_OK,
"Player required for this status code.");
this.status = status;
player = Optional.empty();
}
@@ -46,7 +48,8 @@ public final class PlayerLoaderResponse {
* @throws NullPointerException If the specified player is null.
*/
public PlayerLoaderResponse(int status, Player player) {
Preconditions.checkArgument(status == LoginConstants.STATUS_OK || status == LoginConstants.STATUS_RECONNECTION_OK, "Player not required for this status code.");
Preconditions.checkArgument(status == LoginConstants.STATUS_OK || status == LoginConstants.STATUS_RECONNECTION_OK,
"Player not required for this status code.");
this.status = status;
this.player = Optional.of(player);
}
-21
View File
@@ -1,21 +0,0 @@
package org.apollo.io.player;
import org.apollo.game.model.entity.Player;
/**
* An interface which may be implemented by others which are capable of saving players. For example, implementations
* might include text-based, binary and SQL savers.
*
* @author Graham
*/
public interface PlayerSaver {
/**
* Saves a player.
*
* @param player The player to save.
* @throws Exception If an error occurs.
*/
public void savePlayer(Player player) throws Exception;
}
@@ -0,0 +1,38 @@
package org.apollo.io.player;
import org.apollo.game.model.Position;
import org.apollo.game.model.entity.Player;
import org.apollo.security.PlayerCredentials;
/**
* An interface which may be implemented by others which are capable of serializing and deserializing players. For
* example, implementations might include text-based, binary and SQL serializers.
*
* @author Graham
* @author Major
*/
public interface PlayerSerializer {
/**
* The spawn point for Players, on Tutorial Island.
*/
Position TUTORIAL_ISLAND_SPAWN = new Position(3093, 3104);
/**
* Loads a {@link Player}.
*
* @param credentials The {@link PlayerCredentials}.
* @return The {@link PlayerLoaderResponse}.
* @throws Exception If an error occurs.
*/
public PlayerLoaderResponse loadPlayer(PlayerCredentials credentials) throws Exception;
/**
* Saves a {@link Player}.
*
* @param player The Player to save.
* @throws Exception If an error occurs.
*/
public void savePlayer(Player player) throws Exception;
}
@@ -1,126 +0,0 @@
package org.apollo.io.player.impl;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;
import org.apollo.game.model.Appearance;
import org.apollo.game.model.Item;
import org.apollo.game.model.Position;
import org.apollo.game.model.entity.Player;
import org.apollo.game.model.entity.Skill;
import org.apollo.game.model.entity.SkillSet;
import org.apollo.game.model.entity.attr.Attribute;
import org.apollo.game.model.entity.attr.AttributeMap;
import org.apollo.game.model.entity.attr.AttributePersistence;
import org.apollo.game.model.inv.Inventory;
import org.apollo.io.player.PlayerSaver;
import org.apollo.util.NameUtil;
import org.apollo.util.StreamUtil;
/**
* A {@link PlayerSaver} implementation that saves player data to a binary file.
*
* @author Graham
*/
public final class BinaryPlayerSaver implements PlayerSaver {
@Override
public void savePlayer(Player player) throws IOException {
File file = BinaryPlayerUtil.getFile(player.getUsername());
try (DataOutputStream out = new DataOutputStream(new FileOutputStream(file))) {
StreamUtil.writeString(out, player.getUsername());
StreamUtil.writeString(out, player.getCredentials().getPassword());
out.writeByte(player.getPrivilegeLevel().toInteger());
out.writeByte(player.getMembershipStatus().getValue());
out.writeByte(player.getChatPrivacy().toInteger(true));
out.writeByte(player.getFriendPrivacy().toInteger(false));
out.writeByte(player.getTradePrivacy().toInteger(false));
out.writeByte(player.getRunEnergy());
out.writeByte(player.getScreenBrightness().toInteger());
Position position = player.getPosition();
out.writeShort(position.getX());
out.writeShort(position.getY());
out.writeByte(position.getHeight());
Appearance appearance = player.getAppearance();
out.writeByte(appearance.getGender().toInteger());
int[] style = appearance.getStyle();
for (int element : style) {
out.writeByte(element);
}
int[] colors = appearance.getColors();
for (int color : colors) {
out.writeByte(color);
}
writeInventory(out, player.getInventory());
writeInventory(out, player.getEquipment());
writeInventory(out, player.getBank());
SkillSet skills = player.getSkillSet();
out.writeByte(skills.size());
for (int id = 0; id < skills.size(); id++) {
Skill skill = skills.getSkill(id);
out.writeByte(skill.getCurrentLevel());
out.writeDouble(skill.getExperience());
}
List<String> usernames = player.getFriendUsernames();
out.writeByte(usernames.size());
for (String username : usernames) {
out.writeLong(NameUtil.encodeBase37(username));
}
usernames = player.getIgnoredUsernames();
out.writeByte(usernames.size());
for (String username : usernames) {
out.writeLong(NameUtil.encodeBase37(username));
}
Set<Entry<String, Attribute<?>>> attributes = player.getAttributes().entrySet();
attributes.removeIf(e -> AttributeMap.getDefinition(e.getKey()).getPersistence() != AttributePersistence.PERSISTENT);
out.writeInt(attributes.size());
for (Entry<String, Attribute<?>> entry : attributes) {
String name = entry.getKey();
StreamUtil.writeString(out, name);
Attribute<?> attribute = entry.getValue();
out.writeByte(attribute.getType().getValue());
out.write(attribute.encode());
}
}
}
/**
* Writes an inventory to the specified output stream.
*
* @param out The output stream.
* @param inventory The inventory.
* @throws IOException If an I/O error occurs.
*/
private static void writeInventory(DataOutputStream out, Inventory inventory) throws IOException {
int capacity = inventory.capacity();
out.writeShort(capacity);
for (int slot = 0; slot < capacity; slot++) {
Item item = inventory.get(slot);
if (item != null) {
out.writeShort(item.getId() + 1);
out.writeInt(item.getAmount());
} else {
out.writeShort(0);
out.writeInt(0);
}
}
}
}
@@ -1,46 +0,0 @@
package org.apollo.io.player.impl;
import java.io.File;
import org.apollo.util.NameUtil;
/**
* A utility class with common functionality used by the binary player loader/ savers.
*
* @author Graham
*/
public final class BinaryPlayerUtil {
/**
* The saved games directory.
*/
private static final File SAVED_GAMES_DIRECTORY = new File("data/savedGames");
/**
* Creates the saved games directory if it does not exist.
*/
static {
if (!SAVED_GAMES_DIRECTORY.exists()) {
SAVED_GAMES_DIRECTORY.mkdir();
}
}
/**
* Gets the save {@link File} for the specified player.
*
* @param username The username of the player.
* @return The file.
*/
public static File getFile(String username) {
String filtered = NameUtil.decodeBase37(NameUtil.encodeBase37(username));
return new File(SAVED_GAMES_DIRECTORY, filtered + ".dat");
}
/**
* Default private constructor to prevent instantiation.
*/
private BinaryPlayerUtil() {
}
}
@@ -1,18 +0,0 @@
package org.apollo.io.player.impl;
import org.apollo.game.model.entity.Player;
import org.apollo.io.player.PlayerSaver;
/**
* A {@link PlayerSaver} implementation that discards player data.
*
* @author Graham
*/
public final class DiscardPlayerSaver implements PlayerSaver {
@Override
public void savePlayer(Player player) {
/* discard player */
}
}
@@ -1,19 +0,0 @@
package org.apollo.io.player.impl;
import org.apollo.io.player.PlayerLoader;
import org.apollo.io.player.PlayerLoaderResponse;
import org.apollo.security.PlayerCredentials;
/**
* A {@link PlayerLoader} that utilises {@code JDBC} to load player files.
*
* @author Major
*/
public final class JdbcPlayerLoader implements PlayerLoader {
@Override
public PlayerLoaderResponse loadPlayer(PlayerCredentials credentials) throws Exception {
throw new UnsupportedOperationException("JDBC loading is not supported at this time.");
}
}
@@ -1,18 +0,0 @@
package org.apollo.io.player.impl;
import org.apollo.game.model.entity.Player;
import org.apollo.io.player.PlayerSaver;
/**
* A {@link PlayerSaver} that utilises {@code JDBC} to save the player.
*
* @author Major
*/
public final class JdbcPlayerSaver implements PlayerSaver {
@Override
public void savePlayer(Player player) throws Exception {
throw new UnsupportedOperationException("JDBC saving is not supported at this time.");
}
}
@@ -1,4 +0,0 @@
/**
* Contains various player loader/saver implementations.
*/
package org.apollo.io.player.impl;
+13 -26
View File
@@ -8,9 +8,8 @@ import java.util.concurrent.Executors;
import org.apollo.Service;
import org.apollo.game.model.entity.Player;
import org.apollo.io.player.PlayerLoader;
import org.apollo.io.player.PlayerLoaderResponse;
import org.apollo.io.player.PlayerSaver;
import org.apollo.io.player.PlayerSerializer;
import org.apollo.net.codec.login.LoginConstants;
import org.apollo.net.codec.login.LoginRequest;
import org.apollo.net.release.Release;
@@ -25,6 +24,7 @@ import org.xml.sax.SAXException;
* The {@link LoginService} manages {@link LoginRequest}s.
*
* @author Graham
* @author Major
*/
public final class LoginService extends Service {
@@ -34,14 +34,9 @@ public final class LoginService extends Service {
private final ExecutorService executor = Executors.newCachedThreadPool(new NamedThreadFactory("LoginService"));
/**
* The current {@link PlayerLoader}.
* The current {@link PlayerSerializer}.
*/
private PlayerLoader loader;
/**
* The current {@link PlayerSaver}.
*/
private PlayerSaver saver;
private PlayerSerializer serializer;
/**
* Creates the login service.
@@ -70,24 +65,16 @@ public final class LoginService extends Service {
}
if (!rootNode.getName().equals("login")) {
throw new IOException("Unexpected root node name.");
throw new IOException("Unexpected root node name, expected 'login'.");
}
XmlNode loaderNode = rootNode.getChild("loader");
if (loaderNode == null || !loaderNode.hasValue()) {
throw new IOException("No loader child node or value.");
XmlNode serializer = rootNode.getChild("serializer");
if (serializer == null || !serializer.hasValue()) {
throw new IOException("No serializer child node or value.");
}
XmlNode saverNode = rootNode.getChild("saver");
if (saverNode == null || !saverNode.hasValue()) {
throw new IOException("No saver child node or value.");
}
Class<?> loaderClazz = Class.forName(loaderNode.getValue());
Class<?> saverClazz = Class.forName(saverNode.getValue());
loader = (PlayerLoader) loaderClazz.newInstance();
saver = (PlayerSaver) saverClazz.newInstance();
Class<?> clazz = Class.forName(serializer.getValue());
this.serializer = (PlayerSerializer) clazz.newInstance();
}
/**
@@ -95,7 +82,7 @@ public final class LoginService extends Service {
*/
@Override
public void start() {
/* empty - here for consistency with other services */
}
/**
@@ -110,7 +97,7 @@ public final class LoginService extends Service {
// TODO check archive 0 CRCs
session.handlePlayerLoaderResponse(request, new PlayerLoaderResponse(LoginConstants.STATUS_GAME_UPDATED));
} else {
executor.submit(new PlayerLoaderWorker(loader, session, request));
executor.submit(new PlayerLoaderWorker(serializer, session, request));
}
}
@@ -121,7 +108,7 @@ public final class LoginService extends Service {
* @param player The player to save.
*/
public void submitSaveRequest(GameSession session, Player player) {
executor.submit(new PlayerSaverWorker(saver, session, player));
executor.submit(new PlayerSaverWorker(serializer, session, player));
}
}
+5 -5
View File
@@ -3,8 +3,8 @@ package org.apollo.login;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apollo.io.player.PlayerLoader;
import org.apollo.io.player.PlayerLoaderResponse;
import org.apollo.io.player.PlayerSerializer;
import org.apollo.net.codec.login.LoginConstants;
import org.apollo.net.codec.login.LoginRequest;
import org.apollo.net.session.LoginSession;
@@ -22,9 +22,9 @@ public final class PlayerLoaderWorker implements Runnable {
private static final Logger logger = Logger.getLogger(PlayerLoaderWorker.class.getName());
/**
* The player loader.
* The PlayerSerializer.
*/
private final PlayerLoader loader;
private final PlayerSerializer loader;
/**
* The request.
@@ -39,11 +39,11 @@ public final class PlayerLoaderWorker implements Runnable {
/**
* Creates a {@link PlayerLoaderWorker} which will do the work for a single player load request.
*
* @param loader The current player loader.
* @param loader The {@link PlayerSerializer}.
* @param session The {@link LoginSession} which initiated the request.
* @param request The {@link LoginRequest} object.
*/
public PlayerLoaderWorker(PlayerLoader loader, LoginSession session, LoginRequest request) {
public PlayerLoaderWorker(PlayerSerializer loader, LoginSession session, LoginRequest request) {
this.loader = loader;
this.session = session;
this.request = request;
+3 -3
View File
@@ -4,7 +4,7 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import org.apollo.game.model.entity.Player;
import org.apollo.io.player.PlayerSaver;
import org.apollo.io.player.PlayerSerializer;
import org.apollo.net.session.GameSession;
/**
@@ -27,7 +27,7 @@ public final class PlayerSaverWorker implements Runnable {
/**
* The player saver.
*/
private final PlayerSaver saver;
private final PlayerSerializer saver;
/**
* The game session.
@@ -41,7 +41,7 @@ public final class PlayerSaverWorker implements Runnable {
* @param session The game session.
* @param player The player to save.
*/
public PlayerSaverWorker(PlayerSaver saver, GameSession session, Player player) {
public PlayerSaverWorker(PlayerSerializer saver, GameSession session, Player player) {
this.saver = saver;
this.session = session;
this.player = player;