From 03c1fe16ac1a41a3acaba430d98e43c8bfce8b2d Mon Sep 17 00:00:00 2001 From: Major- Date: Mon, 2 Mar 2015 03:57:15 +0000 Subject: [PATCH] Improve attributes code. --- data/plugins/entity/attributes/attributes.rb | 32 ++++---- .../impl/PlayerDesignMessageHandler.java | 1 - src/org/apollo/game/model/entity/Mob.java | 4 +- src/org/apollo/game/model/entity/Player.java | 75 +++++++------------ .../game/model/entity/attr/Attribute.java | 18 ++++- .../entity/attr/AttributeDefinition.java | 64 +++++++++++++--- .../game/model/entity/attr/AttributeMap.java | 62 +++++++++++++-- .../entity/attr/AttributePersistence.java | 2 +- .../model/entity/attr/BooleanAttribute.java | 10 +++ .../model/entity/attr/NumericalAttribute.java | 13 ++++ .../model/entity/attr/StringAttribute.java | 12 +++ .../io/player/impl/BinaryPlayerLoader.java | 23 ++---- .../io/player/impl/BinaryPlayerSaver.java | 46 ++---------- .../io/player/impl/BinaryPlayerUtil.java | 4 +- 14 files changed, 217 insertions(+), 149 deletions(-) diff --git a/data/plugins/entity/attributes/attributes.rb b/data/plugins/entity/attributes/attributes.rb index 75183026..370593e2 100644 --- a/data/plugins/entity/attributes/attributes.rb +++ b/data/plugins/entity/attributes/attributes.rb @@ -16,7 +16,7 @@ java_import 'org.apollo.game.model.entity.attr.StringAttribute' # Declares an attribute and adds its definition. def declare_attribute(name, default, persistence=:transient) raise "Attribute #{name} clashes with an existing variable." if (Player.method_defined?(name) || Mob.method_defined?(name) || Npc.method_defined?(name)) - AttributeMap::add_definition(name.to_s, AttributeDefinition.new(default, get_persistence(persistence), get_type(default))) + AttributeMap::define(name.to_s, AttributeDefinition.new(default, get_persistence(persistence), get_type(default))) end @@ -25,35 +25,35 @@ private # The existing Mob class. class Mob - # Overrides method_missing + # Overrides method_missing to implement the functionality. def method_missing(symbol, *args) name = symbol.to_s.strip if name[-1] == "=" raise "Expected argument count of 1, received #{args.length}" unless args.length == 1 - name = name[0...-1].strip # Drop the equals + name = name[0...-1].strip # Drop the equals and trim whitespace. set_attribute(name, to_attribute(args[0])) elsif AttributeMap::get_definition(name).nil? super(symbol, *args) else - attribute = get_attribute(name); definition = AttributeMap::get_definition(name) - value = attribute.nil? ? definition.default : attribute.value - - return (definition.type == AttributeType::SYMBOL) ? value.to_sym : value + attribute = get_attribute(name) + value = attribute.value + return (attribute.type == AttributeType::SYMBOL) ? value.to_sym : value end end +end + + # Gets the appropriate attribute for the specified value. - def to_attribute(value) - case value - when String, Symbol then return StringAttribute.new(value.to_s, value.is_a?(Symbol)) - when Integer, Float then return NumericalAttribute.new(value) - when TrueClass, FalseClass then return BooleanAttribute.new(value) - else raise "Undefined attribute type #{value.class}." - end +def to_attribute(value) + case value + when String, Symbol then return StringAttribute.new(value.to_s, value.is_a?(Symbol)) + when Integer, Float then return NumericalAttribute.new(value) + when TrueClass, FalseClass then return BooleanAttribute.new(value) + else raise "Undefined attribute type #{value.class}." end - end # Gets the attribute type of the specified value. @@ -72,5 +72,5 @@ end def get_persistence(persistence) raise "Undefined persistence type #{persistence}." unless [ :persistent, :transient ].include?(persistence) - return (persistence == :persistent) ? AttributePersistence::SERIALIZED : AttributePersistence::TRANSIENT + return (persistence == :persistent) ? AttributePersistence::PERSISTENT : AttributePersistence::TRANSIENT end \ No newline at end of file diff --git a/src/org/apollo/game/message/handler/impl/PlayerDesignMessageHandler.java b/src/org/apollo/game/message/handler/impl/PlayerDesignMessageHandler.java index 7c4db500..7e7ad3af 100644 --- a/src/org/apollo/game/message/handler/impl/PlayerDesignMessageHandler.java +++ b/src/org/apollo/game/message/handler/impl/PlayerDesignMessageHandler.java @@ -16,7 +16,6 @@ public final class PlayerDesignMessageHandler extends MessageHandler getAttribute(String name) { - return attributes.getAttribute(name); + return attributes.get(name); } /** @@ -369,7 +369,7 @@ public abstract class Mob extends Entity { * @param value The attribute. */ public final void setAttribute(String name, Attribute value) { - attributes.setAttribute(name, value); + attributes.set(name, value); } /** diff --git a/src/org/apollo/game/model/entity/Player.java b/src/org/apollo/game/model/entity/Player.java index 50e1aeee..79f9efc1 100644 --- a/src/org/apollo/game/model/entity/Player.java +++ b/src/org/apollo/game/model/entity/Player.java @@ -19,6 +19,11 @@ import org.apollo.game.model.Appearance; import org.apollo.game.model.Position; import org.apollo.game.model.World; import org.apollo.game.model.area.Sector; +import org.apollo.game.model.entity.attr.Attribute; +import org.apollo.game.model.entity.attr.AttributeDefinition; +import org.apollo.game.model.entity.attr.AttributeMap; +import org.apollo.game.model.entity.attr.AttributePersistence; +import org.apollo.game.model.entity.attr.NumericalAttribute; import org.apollo.game.model.entity.setting.MembershipStatus; import org.apollo.game.model.entity.setting.PrivacyState; import org.apollo.game.model.entity.setting.PrivilegeLevel; @@ -55,6 +60,11 @@ import com.google.common.base.Preconditions; */ public final class Player extends Mob { + static { + AttributeMap.define("run_energy", AttributeDefinition.forInt(100, AttributePersistence.PERSISTENT)); + AttributeMap.define("client_version", AttributeDefinition.forInt(0, AttributePersistence.TRANSIENT)); + } + /** * The player's appearance. */ @@ -75,12 +85,6 @@ public final class Player extends Mob { */ private transient Deque clicks = new ArrayDeque<>(); - /** - * The version of the client this player is using. This is not the same as the release number, instead denoting the - * custom version. - */ - private transient int clientVersion; - /** * This player's credentials. */ @@ -136,11 +140,6 @@ public final class Player extends Mob { */ private transient MembershipStatus members = MembershipStatus.FREE; - /** - * A flag indicating if the player is new. - */ - private boolean newPlayer = false; - /** * This player's prayer icon. */ @@ -156,11 +155,6 @@ public final class Player extends Mob { */ private final transient Deque queuedMessages = new ArrayDeque<>(); - /** - * The player's run energy. - */ - private int runEnergy = 100; - /** * A flag indicating if this player is running. */ @@ -327,7 +321,8 @@ public final class Player extends Mob { * @return The version. */ public int getClientVersion() { - return clientVersion; + Attribute version = attributes.get("client_version"); + return version.getValue(); } /** @@ -436,7 +431,8 @@ public final class Player extends Mob { * @return The run energy. */ public int getRunEnergy() { - return runEnergy; + Attribute energy = attributes.get("run_energy"); + return energy.getValue(); } /** @@ -571,15 +567,6 @@ public final class Player extends Mob { return members; } - /** - * Checks if this player has logged in before. - * - * @return A flag indicating if the player is new. - */ - public boolean isNew() { - return newPlayer; - } - /** * Checks if this player is running. * @@ -701,9 +688,6 @@ public final class Player extends Mob { blockSet.add(SynchronizationBlock.createAppearanceBlock(this)); send(new IdAssignmentMessage(index, members)); // TODO should this be sent when we reconnect? sendMessage("Welcome to RuneScape."); - if (newPlayer) { - interfaceSet.openWindow(InterfaceConstants.AVATAR_DESIGN); - } int[] tabs = InterfaceConstants.DEFAULT_INVENTORY_TABS; for (int tab = 0; tab < tabs.length; tab++) { @@ -734,7 +718,7 @@ public final class Player extends Mob { * @param filterable Whether or not the message can be filtered. */ public void sendMessage(String message, boolean filterable) { - if (clientVersion > 0) { + if (getClientVersion() > 0) { send(new ServerChatMessage(message, filterable)); } else if (!filterable || !filteringMessages) { send(new ServerChatMessage(message)); @@ -791,12 +775,12 @@ public final class Player extends Mob { } /** - * Sets the value denoting the client's modified version. TODO make this an attribute? + * Sets the value denoting the client's modified version. * - * @param clientVersion The client version. + * @param version The client version. */ - public void setClientVersion(int clientVersion) { - this.clientVersion = clientVersion; + public void setClientVersion(int version) { + attributes.set("client_version", new NumericalAttribute(version)); } /** @@ -844,15 +828,6 @@ public final class Player extends Mob { this.members = members; } - /** - * Sets the new player flag. TODO make this an attribute? - * - * @param newPlayer A flag indicating if the player has played before. - */ - public void setNew(boolean newPlayer) { - this.newPlayer = newPlayer; - } - /** * Sets the player's prayer icon. TODO make this an attribute? * @@ -872,13 +847,13 @@ public final class Player extends Mob { } /** - * Sets the player's run energy. TODO make this an attribute? + * Sets the player's run energy. * - * @param runEnergy The energy. + * @param energy The energy. */ - public void setRunEnergy(int runEnergy) { - this.runEnergy = runEnergy; - send(new UpdateRunEnergyMessage(runEnergy)); + public void setRunEnergy(int energy) { + attributes.set("run_energy", new NumericalAttribute(energy)); + send(new UpdateRunEnergyMessage(energy)); } /** @@ -969,7 +944,7 @@ public final class Player extends Mob { @Override public String toString() { return MoreObjects.toStringHelper(this).add("username", getUsername()).add("privilege", privilegeLevel) - .add("client version", clientVersion).toString(); + .add("client version", getClientVersion()).toString(); } /** diff --git a/src/org/apollo/game/model/entity/attr/Attribute.java b/src/org/apollo/game/model/entity/attr/Attribute.java index 9fff080f..6627b8a0 100644 --- a/src/org/apollo/game/model/entity/attr/Attribute.java +++ b/src/org/apollo/game/model/entity/attr/Attribute.java @@ -13,12 +13,12 @@ public abstract class Attribute { /** * The type of this attribute. */ - private final AttributeType type; + protected final AttributeType type; /** * The value of this attribute. */ - protected T value; + protected final T value; /** * Creates the attribute with the specified {@link AttributeType} and value. @@ -31,6 +31,13 @@ public abstract class Attribute { this.value = value; } + /** + * Encodes this Attribute into a byte array. + * + * @return The byte array. + */ + public abstract byte[] encode(); + /** * Gets the type of this attribute. * @@ -49,4 +56,11 @@ public abstract class Attribute { return value; } + /** + * Returns the Sting representation of this Attribute. Will be used to write this Attribute as a String, if + * required. + */ + @Override + public abstract String toString(); + } \ No newline at end of file diff --git a/src/org/apollo/game/model/entity/attr/AttributeDefinition.java b/src/org/apollo/game/model/entity/attr/AttributeDefinition.java index 9a48b15d..0f4092b1 100644 --- a/src/org/apollo/game/model/entity/attr/AttributeDefinition.java +++ b/src/org/apollo/game/model/entity/attr/AttributeDefinition.java @@ -10,25 +10,69 @@ package org.apollo.game.model.entity.attr; public final class AttributeDefinition { /** - * The default value of this definition. + * Creates an AttributeDefinition for a {@code boolean}. + * + * @param defaultValue The default value of the definition. + * @param persistence The {@link AttributePersistence} of the definition. + * @return The AttributeDefinition. + */ + public static AttributeDefinition forBoolean(boolean defaultValue, AttributePersistence persistence) { + return new AttributeDefinition<>(defaultValue, persistence, AttributeType.BOOLEAN); + } + + /** + * Creates an AttributeDefinition for a {@code double}. + * + * @param defaultValue The default value of the definition. + * @param persistence The {@link AttributePersistence} of the definition. + * @return The AttributeDefinition. + */ + public static AttributeDefinition forDouble(double defaultValue, AttributePersistence persistence) { + return new AttributeDefinition<>(defaultValue, persistence, AttributeType.DOUBLE); + } + + /** + * Creates an AttributeDefinition for an {@code int}. + * + * @param defaultValue The default value of the definition. + * @param persistence The {@link AttributePersistence} of the definition. + * @return The AttributeDefinition. + */ + public static AttributeDefinition forInt(int defaultValue, AttributePersistence persistence) { + return new AttributeDefinition<>(defaultValue, persistence, AttributeType.LONG); + } + + /** + * Creates an AttributeDefinition for a String. + * + * @param defaultValue The default value of the definition. + * @param persistence The {@link AttributePersistence} of the definition. + * @return The AttributeDefinition. + */ + public static AttributeDefinition forString(String defaultValue, AttributePersistence persistence) { + return new AttributeDefinition<>(defaultValue, persistence, AttributeType.STRING); + } + + /** + * The default value of the Attribute. */ private final T defaultValue; /** - * The persistence state of this definition. + * The persistence state of the Attribute. */ private final AttributePersistence persistence; /** - * The type of this definition. + * The type of the Attribute. */ private final AttributeType type; /** - * Creates the attribute definition. + * Creates the AttributeDefinition. * * @param defaultValue The default value. - * @param persistence The {@link AttributePersistence} state. + * @param persistence The {@link AttributePersistence}. * @param type The {@link AttributeType}. */ public AttributeDefinition(T defaultValue, AttributePersistence persistence, AttributeType type) { @@ -38,7 +82,7 @@ public final class AttributeDefinition { } /** - * Gets the default value of this attribute definition. + * Gets the default value of this AttributeDefinition. * * @return The default value. */ @@ -47,18 +91,18 @@ public final class AttributeDefinition { } /** - * Gets the persistence state of this attribute definition. + * Gets the {@link AttributePersistence} of this AttributeDefinition. * - * @return The persistence. + * @return The AttributePersistence. */ public AttributePersistence getPersistence() { return persistence; } /** - * Gets the {@link AttributeType} of this definition. + * Gets the {@link AttributeType} of this AttributeDefinition * - * @return The attribute type. + * @return The AttributeType. */ public AttributeType getType() { return type; diff --git a/src/org/apollo/game/model/entity/attr/AttributeMap.java b/src/org/apollo/game/model/entity/attr/AttributeMap.java index 0d79d68e..e1f0ce9b 100644 --- a/src/org/apollo/game/model/entity/attr/AttributeMap.java +++ b/src/org/apollo/game/model/entity/attr/AttributeMap.java @@ -3,6 +3,8 @@ package org.apollo.game.model.entity.attr; import java.util.HashMap; import java.util.Map; +import org.jruby.RubySymbol; + import com.google.common.base.Preconditions; /** @@ -12,10 +14,15 @@ import com.google.common.base.Preconditions; */ public final class AttributeMap { + /** + * The default size of the map. + */ + private static final int DEFAULT_MAP_SIZE = 2; + /** * The map of attribute names to definitions. */ - private static Map> definitions = new HashMap<>(1); + private static Map> definitions = new HashMap<>(); /** * Registers an {@link AttributeDefinition}. @@ -23,7 +30,7 @@ public final class AttributeMap { * @param name The name of the attribute. * @param definition The definition. */ - public static void addDefinition(String name, AttributeDefinition definition) { + public static void define(String name, AttributeDefinition definition) { definitions.put(name, definition); } @@ -33,8 +40,9 @@ public final class AttributeMap { * @param name The name of the attribute. * @return The attribute definition. */ - public static AttributeDefinition getDefinition(String name) { - return definitions.get(name); + @SuppressWarnings("unchecked") + public static AttributeDefinition getDefinition(String name) { + return (AttributeDefinition) definitions.get(name); } /** @@ -46,10 +54,20 @@ public final class AttributeMap { return new HashMap<>(definitions); } + /** + * Returns whether or not an {@link AttributeDefinition} with the specified name exists. + * + * @param name The name of the AttributeDefinition. + * @return {@code true} if the AttributeDefinition exists, {@code false} if not. + */ + public static boolean hasDefinition(String name) { + return definitions.containsKey(name); + } + /** * The map of attribute names to attributes. */ - private Map> attributes = new HashMap<>(); + private Map> attributes = new HashMap<>(DEFAULT_MAP_SIZE); /** * Gets the {@link Attribute} with the specified name. @@ -57,8 +75,13 @@ public final class AttributeMap { * @param name The name of the attribute. * @return The attribute. */ - public Attribute getAttribute(String name) { - return attributes.get(name); + @SuppressWarnings("unchecked") + public Attribute get(String name) { + AttributeDefinition definition = getDefinition(name); + Preconditions.checkNotNull(definition, "Attributes must be defined before their value can be retreived."); + + return (Attribute) attributes.computeIfAbsent(name, + key -> createAttribute(definition.getDefault(), definition.getType())); } /** @@ -76,9 +99,32 @@ public final class AttributeMap { * @param name The name of the attribute. * @param attribute The attribute. */ - public void setAttribute(String name, Attribute attribute) { + public void set(String name, Attribute attribute) { Preconditions.checkNotNull(getDefinition(name), "Attributes must be defined before their value can be set."); attributes.put(name, attribute); } + /** + * Creates an {@link Attribute} with the specified value and {@link AttributeType}. + * + * @param value The value of the Attribute. + * @param type The AttributeType. + * @return The Attribute. + */ + private Attribute createAttribute(T value, AttributeType type) { + switch (type) { + case LONG: + case DOUBLE: + return new NumericalAttribute((Integer) value); + case STRING: + return new StringAttribute((String) value); + case SYMBOL: + return new StringAttribute(((RubySymbol) value).asJavaString(), true); + case BOOLEAN: + return new BooleanAttribute((Boolean) value); + } + + throw new IllegalArgumentException("Unrecognised type " + type + "."); + } + } \ No newline at end of file diff --git a/src/org/apollo/game/model/entity/attr/AttributePersistence.java b/src/org/apollo/game/model/entity/attr/AttributePersistence.java index 29cb365f..5c86de00 100644 --- a/src/org/apollo/game/model/entity/attr/AttributePersistence.java +++ b/src/org/apollo/game/model/entity/attr/AttributePersistence.java @@ -8,7 +8,7 @@ public enum AttributePersistence { /** * The serialized persistence type, indicating that the attribute will be saved. */ - SERIALIZED, + PERSISTENT, /** * The transient persistence type, indicating that the attribute will not be saved. diff --git a/src/org/apollo/game/model/entity/attr/BooleanAttribute.java b/src/org/apollo/game/model/entity/attr/BooleanAttribute.java index e5409c66..e9df53d1 100644 --- a/src/org/apollo/game/model/entity/attr/BooleanAttribute.java +++ b/src/org/apollo/game/model/entity/attr/BooleanAttribute.java @@ -16,4 +16,14 @@ public final class BooleanAttribute extends Attribute { super(AttributeType.BOOLEAN, value); } + @Override + public byte[] encode() { + return new byte[] { (byte) (value ? 1 : 0) }; + } + + @Override + public String toString() { + return Boolean.toString(value); + } + } \ No newline at end of file diff --git a/src/org/apollo/game/model/entity/attr/NumericalAttribute.java b/src/org/apollo/game/model/entity/attr/NumericalAttribute.java index a7f21982..ffc3915b 100644 --- a/src/org/apollo/game/model/entity/attr/NumericalAttribute.java +++ b/src/org/apollo/game/model/entity/attr/NumericalAttribute.java @@ -1,5 +1,7 @@ package org.apollo.game.model.entity.attr; +import com.google.common.primitives.Longs; + /** * An {@link Attribute} with a numerical value. * @@ -26,4 +28,15 @@ public final class NumericalAttribute extends Attribute { super(typeOf(value), value); } + @Override + public byte[] encode() { + long encoded = (type == AttributeType.DOUBLE) ? Double.doubleToLongBits((double) value) : (long) value; + return Longs.toByteArray(encoded); + } + + @Override + public String toString() { + return (type == AttributeType.DOUBLE) ? Double.toString((double) value) : Long.toString((long) value); + } + } \ No newline at end of file diff --git a/src/org/apollo/game/model/entity/attr/StringAttribute.java b/src/org/apollo/game/model/entity/attr/StringAttribute.java index be7c763c..6468ee11 100644 --- a/src/org/apollo/game/model/entity/attr/StringAttribute.java +++ b/src/org/apollo/game/model/entity/attr/StringAttribute.java @@ -1,5 +1,7 @@ package org.apollo.game.model.entity.attr; +import java.nio.charset.Charset; + /** * An {@link Attribute} with a string value. * @@ -26,4 +28,14 @@ public final class StringAttribute extends Attribute { super(symbol ? AttributeType.SYMBOL : AttributeType.STRING, value); } + @Override + public byte[] encode() { + return value.getBytes(Charset.forName("UTF-8")); + } + + @Override + public String toString() { + return value; + } + } \ No newline at end of file diff --git a/src/org/apollo/io/player/impl/BinaryPlayerLoader.java b/src/org/apollo/io/player/impl/BinaryPlayerLoader.java index 204dbe43..19d77500 100644 --- a/src/org/apollo/io/player/impl/BinaryPlayerLoader.java +++ b/src/org/apollo/io/player/impl/BinaryPlayerLoader.java @@ -58,35 +58,28 @@ public final class BinaryPlayerLoader implements PlayerLoader { } try (DataInputStream in = new DataInputStream(new FileInputStream(file))) { - // read credentials and privileges String name = StreamUtil.readString(in); - String pass = StreamUtil.readString(in); + String password = StreamUtil.readString(in); - if (!name.equalsIgnoreCase(credentials.getUsername()) || !SCryptUtil.check(credentials.getPassword(), pass)) { + if (!name.equalsIgnoreCase(credentials.getUsername()) || !SCryptUtil.check(credentials.getPassword(), password)) { return new PlayerLoaderResponse(LoginConstants.STATUS_INVALID_CREDENTIALS); } - // set the credentials password to the scrypted one - credentials.setPassword(pass); + credentials.setPassword(password); // Update password to the hashed one. PrivilegeLevel privilegeLevel = PrivilegeLevel.valueOf(in.readByte()); MembershipStatus members = MembershipStatus.valueOf(in.readByte()); - // read settings 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()); - // read position int x = in.readUnsignedShort(); int y = in.readUnsignedShort(); int height = in.readUnsignedByte(); - // read appearance - boolean designed = in.readBoolean(); - int genderIntValue = in.readUnsignedByte(); Gender gender = genderIntValue == Gender.MALE.toInteger() ? Gender.MALE : Gender.FEMALE; int[] style = new int[7]; @@ -107,15 +100,12 @@ public final class BinaryPlayerLoader implements PlayerLoader { player.setRunEnergy(runEnergy); player.setScreenBrightness(brightness); - player.setNew(designed); player.setAppearance(new Appearance(gender, style, colors)); - // read inventories readInventory(in, player.getInventory()); readInventory(in, player.getEquipment()); readInventory(in, player.getBank()); - // read skills int size = in.readUnsignedByte(); SkillSet skills = player.getSkillSet(); skills.stopFiringEvents(); @@ -139,7 +129,7 @@ public final class BinaryPlayerLoader implements PlayerLoader { int ignoreCount = in.readByte(); List ignores = new ArrayList<>(ignoreCount); - for (int i = 0; i < ignoreCount; i++) { + for (int times = 0; times < ignoreCount; times++) { ignores.add(NameUtil.decodeBase37(in.readLong())); } player.setIgnoredUsernames(ignores); @@ -161,11 +151,12 @@ public final class BinaryPlayerLoader implements PlayerLoader { private static Map> readAttributes(DataInputStream in) throws IOException { int count = in.readInt(); Map> attributes = new HashMap<>(count); - Attribute attribute; - for (int i = 0; i < count; i++) { + for (int times = 0; times < count; times++) { String name = StreamUtil.readString(in); AttributeType type = AttributeType.valueOf(in.read()); + Attribute attribute; + switch (type) { case BOOLEAN: attribute = new BooleanAttribute(in.read() == 1); diff --git a/src/org/apollo/io/player/impl/BinaryPlayerSaver.java b/src/org/apollo/io/player/impl/BinaryPlayerSaver.java index 5a0f9e50..5fca15a2 100644 --- a/src/org/apollo/io/player/impl/BinaryPlayerSaver.java +++ b/src/org/apollo/io/player/impl/BinaryPlayerSaver.java @@ -17,7 +17,6 @@ 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.inv.Inventory; import org.apollo.io.player.PlayerSaver; import org.apollo.util.NameUtil; @@ -35,27 +34,22 @@ public final class BinaryPlayerSaver implements PlayerSaver { File file = BinaryPlayerUtil.getFile(player.getUsername()); try (DataOutputStream out = new DataOutputStream(new FileOutputStream(file))) { - // write credentials and privileges StreamUtil.writeString(out, player.getUsername()); StreamUtil.writeString(out, player.getCredentials().getPassword()); out.writeByte(player.getPrivilegeLevel().toInteger()); out.writeByte(player.getMembershipStatus().getValue()); - // write settings 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()); - // write position Position position = player.getPosition(); out.writeShort(position.getX()); out.writeShort(position.getY()); out.writeByte(position.getHeight()); - // write appearance - out.writeBoolean(player.isNew()); Appearance appearance = player.getAppearance(); out.writeByte(appearance.getGender().toInteger()); int[] style = appearance.getStyle(); @@ -66,14 +60,11 @@ public final class BinaryPlayerSaver implements PlayerSaver { for (int color : colors) { out.writeByte(color); } - out.flush(); - // write inventories writeInventory(out, player.getInventory()); writeInventory(out, player.getEquipment()); writeInventory(out, player.getBank()); - // write skills SkillSet skills = player.getSkillSet(); out.writeByte(skills.size()); for (int id = 0; id < skills.size(); id++) { @@ -95,47 +86,20 @@ public final class BinaryPlayerSaver implements PlayerSaver { } Set>> attributes = player.getAttributes().entrySet(); - attributes.removeIf(e -> AttributeMap.getDefinition(e.getKey()).getPersistence() != AttributePersistence.SERIALIZED); + attributes.removeIf(e -> AttributeMap.getDefinition(e.getKey()).getPersistence() != AttributePersistence.PERSISTENT); out.writeInt(attributes.size()); for (Entry> entry : attributes) { String name = entry.getKey(); StreamUtil.writeString(out, name); - saveAttribute(out, entry.getValue()); + + Attribute attribute = entry.getValue(); + out.writeByte(attribute.getType().getValue()); + out.write(attribute.encode()); } } } - /** - * Writes an {@link Attribute} to the specified output stream. - * - * @param out The output stream. - * @param attribute The attribute. - * @throws IOException If an I/O error occurs. - */ - private static void saveAttribute(DataOutputStream out, Attribute attribute) throws IOException { - AttributeType type = attribute.getType(); - - out.writeByte(type.getValue()); - switch (type) { - case BOOLEAN: - out.writeByte((Boolean) attribute.getValue() ? 1 : 0); - break; - case DOUBLE: - out.writeDouble((Double) attribute.getValue()); - break; - case LONG: - out.writeLong((Long) attribute.getValue()); - break; - case STRING: - case SYMBOL: - StreamUtil.writeString(out, (String) attribute.getValue()); - break; - default: - throw new IllegalArgumentException("Undefined attribute type " + type + "."); - } - } - /** * Writes an inventory to the specified output stream. * diff --git a/src/org/apollo/io/player/impl/BinaryPlayerUtil.java b/src/org/apollo/io/player/impl/BinaryPlayerUtil.java index 85ce31b5..9c4ca633 100644 --- a/src/org/apollo/io/player/impl/BinaryPlayerUtil.java +++ b/src/org/apollo/io/player/impl/BinaryPlayerUtil.java @@ -32,8 +32,8 @@ public final class BinaryPlayerUtil { * @return The file. */ public static File getFile(String username) { - username = NameUtil.decodeBase37(NameUtil.encodeBase37(username)); - return new File(SAVED_GAMES_DIRECTORY, username + ".dat"); + String filtered = NameUtil.decodeBase37(NameUtil.encodeBase37(username)); + return new File(SAVED_GAMES_DIRECTORY, filtered + ".dat"); } /**