mirror of
https://github.com/2006-Scape/apollo.git
synced 2026-07-05 16:49:04 +00:00
Improve attributes code.
This commit is contained in:
@@ -16,7 +16,7 @@ java_import 'org.apollo.game.model.entity.attr.StringAttribute'
|
|||||||
# Declares an attribute and adds its definition.
|
# Declares an attribute and adds its definition.
|
||||||
def declare_attribute(name, default, persistence=:transient)
|
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))
|
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
|
end
|
||||||
|
|
||||||
|
|
||||||
@@ -25,35 +25,35 @@ private
|
|||||||
# The existing Mob class.
|
# The existing Mob class.
|
||||||
class Mob
|
class Mob
|
||||||
|
|
||||||
# Overrides method_missing
|
# Overrides method_missing to implement the functionality.
|
||||||
def method_missing(symbol, *args)
|
def method_missing(symbol, *args)
|
||||||
name = symbol.to_s.strip
|
name = symbol.to_s.strip
|
||||||
|
|
||||||
if name[-1] == "="
|
if name[-1] == "="
|
||||||
raise "Expected argument count of 1, received #{args.length}" unless args.length == 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]))
|
set_attribute(name, to_attribute(args[0]))
|
||||||
elsif AttributeMap::get_definition(name).nil?
|
elsif AttributeMap::get_definition(name).nil?
|
||||||
super(symbol, *args)
|
super(symbol, *args)
|
||||||
else
|
else
|
||||||
attribute = get_attribute(name); definition = AttributeMap::get_definition(name)
|
attribute = get_attribute(name)
|
||||||
value = attribute.nil? ? definition.default : attribute.value
|
value = attribute.value
|
||||||
|
return (attribute.type == AttributeType::SYMBOL) ? value.to_sym : value
|
||||||
return (definition.type == AttributeType::SYMBOL) ? value.to_sym : value
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
# Gets the appropriate attribute for the specified value.
|
# Gets the appropriate attribute for the specified value.
|
||||||
def to_attribute(value)
|
def to_attribute(value)
|
||||||
case value
|
case value
|
||||||
when String, Symbol then return StringAttribute.new(value.to_s, value.is_a?(Symbol))
|
when String, Symbol then return StringAttribute.new(value.to_s, value.is_a?(Symbol))
|
||||||
when Integer, Float then return NumericalAttribute.new(value)
|
when Integer, Float then return NumericalAttribute.new(value)
|
||||||
when TrueClass, FalseClass then return BooleanAttribute.new(value)
|
when TrueClass, FalseClass then return BooleanAttribute.new(value)
|
||||||
else raise "Undefined attribute type #{value.class}."
|
else raise "Undefined attribute type #{value.class}."
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Gets the attribute type of the specified value.
|
# Gets the attribute type of the specified value.
|
||||||
@@ -72,5 +72,5 @@ end
|
|||||||
def get_persistence(persistence)
|
def get_persistence(persistence)
|
||||||
raise "Undefined persistence type #{persistence}." unless [ :persistent, :transient ].include?(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
|
end
|
||||||
@@ -16,7 +16,6 @@ public final class PlayerDesignMessageHandler extends MessageHandler<PlayerDesig
|
|||||||
@Override
|
@Override
|
||||||
public void handle(MessageHandlerContext ctx, Player player, PlayerDesignMessage message) {
|
public void handle(MessageHandlerContext ctx, Player player, PlayerDesignMessage message) {
|
||||||
player.setAppearance(message.getAppearance());
|
player.setAppearance(message.getAppearance());
|
||||||
player.setNew(false);
|
|
||||||
player.send(new CloseInterfaceMessage());
|
player.send(new CloseInterfaceMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ public abstract class Mob extends Entity {
|
|||||||
* @return The value of the attribute.
|
* @return The value of the attribute.
|
||||||
*/
|
*/
|
||||||
public final Attribute<?> getAttribute(String name) {
|
public final Attribute<?> 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.
|
* @param value The attribute.
|
||||||
*/
|
*/
|
||||||
public final void setAttribute(String name, Attribute<?> value) {
|
public final void setAttribute(String name, Attribute<?> value) {
|
||||||
attributes.setAttribute(name, value);
|
attributes.set(name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -19,6 +19,11 @@ import org.apollo.game.model.Appearance;
|
|||||||
import org.apollo.game.model.Position;
|
import org.apollo.game.model.Position;
|
||||||
import org.apollo.game.model.World;
|
import org.apollo.game.model.World;
|
||||||
import org.apollo.game.model.area.Sector;
|
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.MembershipStatus;
|
||||||
import org.apollo.game.model.entity.setting.PrivacyState;
|
import org.apollo.game.model.entity.setting.PrivacyState;
|
||||||
import org.apollo.game.model.entity.setting.PrivilegeLevel;
|
import org.apollo.game.model.entity.setting.PrivilegeLevel;
|
||||||
@@ -55,6 +60,11 @@ import com.google.common.base.Preconditions;
|
|||||||
*/
|
*/
|
||||||
public final class Player extends Mob {
|
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.
|
* The player's appearance.
|
||||||
*/
|
*/
|
||||||
@@ -75,12 +85,6 @@ public final class Player extends Mob {
|
|||||||
*/
|
*/
|
||||||
private transient Deque<Point> clicks = new ArrayDeque<>();
|
private transient Deque<Point> 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.
|
* This player's credentials.
|
||||||
*/
|
*/
|
||||||
@@ -136,11 +140,6 @@ public final class Player extends Mob {
|
|||||||
*/
|
*/
|
||||||
private transient MembershipStatus members = MembershipStatus.FREE;
|
private transient MembershipStatus members = MembershipStatus.FREE;
|
||||||
|
|
||||||
/**
|
|
||||||
* A flag indicating if the player is new.
|
|
||||||
*/
|
|
||||||
private boolean newPlayer = false;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This player's prayer icon.
|
* This player's prayer icon.
|
||||||
*/
|
*/
|
||||||
@@ -156,11 +155,6 @@ public final class Player extends Mob {
|
|||||||
*/
|
*/
|
||||||
private final transient Deque<Message> queuedMessages = new ArrayDeque<>();
|
private final transient Deque<Message> queuedMessages = new ArrayDeque<>();
|
||||||
|
|
||||||
/**
|
|
||||||
* The player's run energy.
|
|
||||||
*/
|
|
||||||
private int runEnergy = 100;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A flag indicating if this player is running.
|
* A flag indicating if this player is running.
|
||||||
*/
|
*/
|
||||||
@@ -327,7 +321,8 @@ public final class Player extends Mob {
|
|||||||
* @return The version.
|
* @return The version.
|
||||||
*/
|
*/
|
||||||
public int getClientVersion() {
|
public int getClientVersion() {
|
||||||
return clientVersion;
|
Attribute<Integer> version = attributes.get("client_version");
|
||||||
|
return version.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -436,7 +431,8 @@ public final class Player extends Mob {
|
|||||||
* @return The run energy.
|
* @return The run energy.
|
||||||
*/
|
*/
|
||||||
public int getRunEnergy() {
|
public int getRunEnergy() {
|
||||||
return runEnergy;
|
Attribute<Integer> energy = attributes.get("run_energy");
|
||||||
|
return energy.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -571,15 +567,6 @@ public final class Player extends Mob {
|
|||||||
return members;
|
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.
|
* Checks if this player is running.
|
||||||
*
|
*
|
||||||
@@ -701,9 +688,6 @@ public final class Player extends Mob {
|
|||||||
blockSet.add(SynchronizationBlock.createAppearanceBlock(this));
|
blockSet.add(SynchronizationBlock.createAppearanceBlock(this));
|
||||||
send(new IdAssignmentMessage(index, members)); // TODO should this be sent when we reconnect?
|
send(new IdAssignmentMessage(index, members)); // TODO should this be sent when we reconnect?
|
||||||
sendMessage("Welcome to RuneScape.");
|
sendMessage("Welcome to RuneScape.");
|
||||||
if (newPlayer) {
|
|
||||||
interfaceSet.openWindow(InterfaceConstants.AVATAR_DESIGN);
|
|
||||||
}
|
|
||||||
|
|
||||||
int[] tabs = InterfaceConstants.DEFAULT_INVENTORY_TABS;
|
int[] tabs = InterfaceConstants.DEFAULT_INVENTORY_TABS;
|
||||||
for (int tab = 0; tab < tabs.length; tab++) {
|
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.
|
* @param filterable Whether or not the message can be filtered.
|
||||||
*/
|
*/
|
||||||
public void sendMessage(String message, boolean filterable) {
|
public void sendMessage(String message, boolean filterable) {
|
||||||
if (clientVersion > 0) {
|
if (getClientVersion() > 0) {
|
||||||
send(new ServerChatMessage(message, filterable));
|
send(new ServerChatMessage(message, filterable));
|
||||||
} else if (!filterable || !filteringMessages) {
|
} else if (!filterable || !filteringMessages) {
|
||||||
send(new ServerChatMessage(message));
|
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) {
|
public void setClientVersion(int version) {
|
||||||
this.clientVersion = clientVersion;
|
attributes.set("client_version", new NumericalAttribute(version));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -844,15 +828,6 @@ public final class Player extends Mob {
|
|||||||
this.members = members;
|
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?
|
* 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) {
|
public void setRunEnergy(int energy) {
|
||||||
this.runEnergy = runEnergy;
|
attributes.set("run_energy", new NumericalAttribute(energy));
|
||||||
send(new UpdateRunEnergyMessage(runEnergy));
|
send(new UpdateRunEnergyMessage(energy));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -969,7 +944,7 @@ public final class Player extends Mob {
|
|||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return MoreObjects.toStringHelper(this).add("username", getUsername()).add("privilege", privilegeLevel)
|
return MoreObjects.toStringHelper(this).add("username", getUsername()).add("privilege", privilegeLevel)
|
||||||
.add("client version", clientVersion).toString();
|
.add("client version", getClientVersion()).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -13,12 +13,12 @@ public abstract class Attribute<T> {
|
|||||||
/**
|
/**
|
||||||
* The type of this attribute.
|
* The type of this attribute.
|
||||||
*/
|
*/
|
||||||
private final AttributeType type;
|
protected final AttributeType type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The value of this attribute.
|
* The value of this attribute.
|
||||||
*/
|
*/
|
||||||
protected T value;
|
protected final T value;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the attribute with the specified {@link AttributeType} and value.
|
* Creates the attribute with the specified {@link AttributeType} and value.
|
||||||
@@ -31,6 +31,13 @@ public abstract class Attribute<T> {
|
|||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encodes this Attribute into a byte array.
|
||||||
|
*
|
||||||
|
* @return The byte array.
|
||||||
|
*/
|
||||||
|
public abstract byte[] encode();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the type of this attribute.
|
* Gets the type of this attribute.
|
||||||
*
|
*
|
||||||
@@ -49,4 +56,11 @@ public abstract class Attribute<T> {
|
|||||||
return value;
|
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();
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -10,25 +10,69 @@ package org.apollo.game.model.entity.attr;
|
|||||||
public final class AttributeDefinition<T> {
|
public final class AttributeDefinition<T> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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<Boolean> 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<Double> 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<Integer> 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<String> forString(String defaultValue, AttributePersistence persistence) {
|
||||||
|
return new AttributeDefinition<>(defaultValue, persistence, AttributeType.STRING);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default value of the Attribute.
|
||||||
*/
|
*/
|
||||||
private final T defaultValue;
|
private final T defaultValue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The persistence state of this definition.
|
* The persistence state of the Attribute.
|
||||||
*/
|
*/
|
||||||
private final AttributePersistence persistence;
|
private final AttributePersistence persistence;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The type of this definition.
|
* The type of the Attribute.
|
||||||
*/
|
*/
|
||||||
private final AttributeType type;
|
private final AttributeType type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the attribute definition.
|
* Creates the AttributeDefinition.
|
||||||
*
|
*
|
||||||
* @param defaultValue The default value.
|
* @param defaultValue The default value.
|
||||||
* @param persistence The {@link AttributePersistence} state.
|
* @param persistence The {@link AttributePersistence}.
|
||||||
* @param type The {@link AttributeType}.
|
* @param type The {@link AttributeType}.
|
||||||
*/
|
*/
|
||||||
public AttributeDefinition(T defaultValue, AttributePersistence persistence, AttributeType type) {
|
public AttributeDefinition(T defaultValue, AttributePersistence persistence, AttributeType type) {
|
||||||
@@ -38,7 +82,7 @@ public final class AttributeDefinition<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the default value of this attribute definition.
|
* Gets the default value of this AttributeDefinition.
|
||||||
*
|
*
|
||||||
* @return The default value.
|
* @return The default value.
|
||||||
*/
|
*/
|
||||||
@@ -47,18 +91,18 @@ public final class AttributeDefinition<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the persistence state of this attribute definition.
|
* Gets the {@link AttributePersistence} of this AttributeDefinition.
|
||||||
*
|
*
|
||||||
* @return The persistence.
|
* @return The AttributePersistence.
|
||||||
*/
|
*/
|
||||||
public AttributePersistence getPersistence() {
|
public AttributePersistence getPersistence() {
|
||||||
return persistence;
|
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() {
|
public AttributeType getType() {
|
||||||
return type;
|
return type;
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ package org.apollo.game.model.entity.attr;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.jruby.RubySymbol;
|
||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -12,10 +14,15 @@ import com.google.common.base.Preconditions;
|
|||||||
*/
|
*/
|
||||||
public final class AttributeMap {
|
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.
|
* The map of attribute names to definitions.
|
||||||
*/
|
*/
|
||||||
private static Map<String, AttributeDefinition<?>> definitions = new HashMap<>(1);
|
private static Map<String, AttributeDefinition<?>> definitions = new HashMap<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers an {@link AttributeDefinition}.
|
* Registers an {@link AttributeDefinition}.
|
||||||
@@ -23,7 +30,7 @@ public final class AttributeMap {
|
|||||||
* @param name The name of the attribute.
|
* @param name The name of the attribute.
|
||||||
* @param definition The definition.
|
* @param definition The definition.
|
||||||
*/
|
*/
|
||||||
public static void addDefinition(String name, AttributeDefinition<?> definition) {
|
public static void define(String name, AttributeDefinition<?> definition) {
|
||||||
definitions.put(name, definition);
|
definitions.put(name, definition);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,8 +40,9 @@ public final class AttributeMap {
|
|||||||
* @param name The name of the attribute.
|
* @param name The name of the attribute.
|
||||||
* @return The attribute definition.
|
* @return The attribute definition.
|
||||||
*/
|
*/
|
||||||
public static AttributeDefinition<?> getDefinition(String name) {
|
@SuppressWarnings("unchecked")
|
||||||
return definitions.get(name);
|
public static <T> AttributeDefinition<T> getDefinition(String name) {
|
||||||
|
return (AttributeDefinition<T>) definitions.get(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -46,10 +54,20 @@ public final class AttributeMap {
|
|||||||
return new HashMap<>(definitions);
|
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.
|
* The map of attribute names to attributes.
|
||||||
*/
|
*/
|
||||||
private Map<String, Attribute<?>> attributes = new HashMap<>();
|
private Map<String, Attribute<?>> attributes = new HashMap<>(DEFAULT_MAP_SIZE);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the {@link Attribute} with the specified name.
|
* Gets the {@link Attribute} with the specified name.
|
||||||
@@ -57,8 +75,13 @@ public final class AttributeMap {
|
|||||||
* @param name The name of the attribute.
|
* @param name The name of the attribute.
|
||||||
* @return The attribute.
|
* @return The attribute.
|
||||||
*/
|
*/
|
||||||
public Attribute<?> getAttribute(String name) {
|
@SuppressWarnings("unchecked")
|
||||||
return attributes.get(name);
|
public <T> Attribute<T> get(String name) {
|
||||||
|
AttributeDefinition<T> definition = getDefinition(name);
|
||||||
|
Preconditions.checkNotNull(definition, "Attributes must be defined before their value can be retreived.");
|
||||||
|
|
||||||
|
return (Attribute<T>) 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 name The name of the attribute.
|
||||||
* @param attribute 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.");
|
Preconditions.checkNotNull(getDefinition(name), "Attributes must be defined before their value can be set.");
|
||||||
attributes.put(name, attribute);
|
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 <T> 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 + ".");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -8,7 +8,7 @@ public enum AttributePersistence {
|
|||||||
/**
|
/**
|
||||||
* The serialized persistence type, indicating that the attribute will be saved.
|
* 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.
|
* The transient persistence type, indicating that the attribute will not be saved.
|
||||||
|
|||||||
@@ -16,4 +16,14 @@ public final class BooleanAttribute extends Attribute<Boolean> {
|
|||||||
super(AttributeType.BOOLEAN, value);
|
super(AttributeType.BOOLEAN, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] encode() {
|
||||||
|
return new byte[] { (byte) (value ? 1 : 0) };
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return Boolean.toString(value);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
package org.apollo.game.model.entity.attr;
|
package org.apollo.game.model.entity.attr;
|
||||||
|
|
||||||
|
import com.google.common.primitives.Longs;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An {@link Attribute} with a numerical value.
|
* An {@link Attribute} with a numerical value.
|
||||||
*
|
*
|
||||||
@@ -26,4 +28,15 @@ public final class NumericalAttribute extends Attribute<Number> {
|
|||||||
super(typeOf(value), value);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
package org.apollo.game.model.entity.attr;
|
package org.apollo.game.model.entity.attr;
|
||||||
|
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An {@link Attribute} with a string value.
|
* An {@link Attribute} with a string value.
|
||||||
*
|
*
|
||||||
@@ -26,4 +28,14 @@ public final class StringAttribute extends Attribute<String> {
|
|||||||
super(symbol ? AttributeType.SYMBOL : AttributeType.STRING, value);
|
super(symbol ? AttributeType.SYMBOL : AttributeType.STRING, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] encode() {
|
||||||
|
return value.getBytes(Charset.forName("UTF-8"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -58,35 +58,28 @@ public final class BinaryPlayerLoader implements PlayerLoader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try (DataInputStream in = new DataInputStream(new FileInputStream(file))) {
|
try (DataInputStream in = new DataInputStream(new FileInputStream(file))) {
|
||||||
// read credentials and privileges
|
|
||||||
String name = StreamUtil.readString(in);
|
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);
|
return new PlayerLoaderResponse(LoginConstants.STATUS_INVALID_CREDENTIALS);
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the credentials password to the scrypted one
|
credentials.setPassword(password); // Update password to the hashed one.
|
||||||
credentials.setPassword(pass);
|
|
||||||
|
|
||||||
PrivilegeLevel privilegeLevel = PrivilegeLevel.valueOf(in.readByte());
|
PrivilegeLevel privilegeLevel = PrivilegeLevel.valueOf(in.readByte());
|
||||||
MembershipStatus members = MembershipStatus.valueOf(in.readByte());
|
MembershipStatus members = MembershipStatus.valueOf(in.readByte());
|
||||||
|
|
||||||
// read settings
|
|
||||||
PrivacyState chatPrivacy = PrivacyState.valueOf(in.readByte(), true);
|
PrivacyState chatPrivacy = PrivacyState.valueOf(in.readByte(), true);
|
||||||
PrivacyState friendPrivacy = PrivacyState.valueOf(in.readByte(), false);
|
PrivacyState friendPrivacy = PrivacyState.valueOf(in.readByte(), false);
|
||||||
PrivacyState tradePrivacy = PrivacyState.valueOf(in.readByte(), false);
|
PrivacyState tradePrivacy = PrivacyState.valueOf(in.readByte(), false);
|
||||||
int runEnergy = in.readByte();
|
int runEnergy = in.readByte();
|
||||||
ScreenBrightness brightness = ScreenBrightness.valueOf(in.readByte());
|
ScreenBrightness brightness = ScreenBrightness.valueOf(in.readByte());
|
||||||
|
|
||||||
// read position
|
|
||||||
int x = in.readUnsignedShort();
|
int x = in.readUnsignedShort();
|
||||||
int y = in.readUnsignedShort();
|
int y = in.readUnsignedShort();
|
||||||
int height = in.readUnsignedByte();
|
int height = in.readUnsignedByte();
|
||||||
|
|
||||||
// read appearance
|
|
||||||
boolean designed = in.readBoolean();
|
|
||||||
|
|
||||||
int genderIntValue = in.readUnsignedByte();
|
int genderIntValue = in.readUnsignedByte();
|
||||||
Gender gender = genderIntValue == Gender.MALE.toInteger() ? Gender.MALE : Gender.FEMALE;
|
Gender gender = genderIntValue == Gender.MALE.toInteger() ? Gender.MALE : Gender.FEMALE;
|
||||||
int[] style = new int[7];
|
int[] style = new int[7];
|
||||||
@@ -107,15 +100,12 @@ public final class BinaryPlayerLoader implements PlayerLoader {
|
|||||||
player.setRunEnergy(runEnergy);
|
player.setRunEnergy(runEnergy);
|
||||||
player.setScreenBrightness(brightness);
|
player.setScreenBrightness(brightness);
|
||||||
|
|
||||||
player.setNew(designed);
|
|
||||||
player.setAppearance(new Appearance(gender, style, colors));
|
player.setAppearance(new Appearance(gender, style, colors));
|
||||||
|
|
||||||
// read inventories
|
|
||||||
readInventory(in, player.getInventory());
|
readInventory(in, player.getInventory());
|
||||||
readInventory(in, player.getEquipment());
|
readInventory(in, player.getEquipment());
|
||||||
readInventory(in, player.getBank());
|
readInventory(in, player.getBank());
|
||||||
|
|
||||||
// read skills
|
|
||||||
int size = in.readUnsignedByte();
|
int size = in.readUnsignedByte();
|
||||||
SkillSet skills = player.getSkillSet();
|
SkillSet skills = player.getSkillSet();
|
||||||
skills.stopFiringEvents();
|
skills.stopFiringEvents();
|
||||||
@@ -139,7 +129,7 @@ public final class BinaryPlayerLoader implements PlayerLoader {
|
|||||||
|
|
||||||
int ignoreCount = in.readByte();
|
int ignoreCount = in.readByte();
|
||||||
List<String> ignores = new ArrayList<>(ignoreCount);
|
List<String> ignores = new ArrayList<>(ignoreCount);
|
||||||
for (int i = 0; i < ignoreCount; i++) {
|
for (int times = 0; times < ignoreCount; times++) {
|
||||||
ignores.add(NameUtil.decodeBase37(in.readLong()));
|
ignores.add(NameUtil.decodeBase37(in.readLong()));
|
||||||
}
|
}
|
||||||
player.setIgnoredUsernames(ignores);
|
player.setIgnoredUsernames(ignores);
|
||||||
@@ -161,11 +151,12 @@ public final class BinaryPlayerLoader implements PlayerLoader {
|
|||||||
private static Map<String, Attribute<?>> readAttributes(DataInputStream in) throws IOException {
|
private static Map<String, Attribute<?>> readAttributes(DataInputStream in) throws IOException {
|
||||||
int count = in.readInt();
|
int count = in.readInt();
|
||||||
Map<String, Attribute<?>> attributes = new HashMap<>(count);
|
Map<String, Attribute<?>> 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);
|
String name = StreamUtil.readString(in);
|
||||||
AttributeType type = AttributeType.valueOf(in.read());
|
AttributeType type = AttributeType.valueOf(in.read());
|
||||||
|
Attribute<?> attribute;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case BOOLEAN:
|
case BOOLEAN:
|
||||||
attribute = new BooleanAttribute(in.read() == 1);
|
attribute = new BooleanAttribute(in.read() == 1);
|
||||||
|
|||||||
@@ -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.Attribute;
|
||||||
import org.apollo.game.model.entity.attr.AttributeMap;
|
import org.apollo.game.model.entity.attr.AttributeMap;
|
||||||
import org.apollo.game.model.entity.attr.AttributePersistence;
|
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.game.model.inv.Inventory;
|
||||||
import org.apollo.io.player.PlayerSaver;
|
import org.apollo.io.player.PlayerSaver;
|
||||||
import org.apollo.util.NameUtil;
|
import org.apollo.util.NameUtil;
|
||||||
@@ -35,27 +34,22 @@ public final class BinaryPlayerSaver implements PlayerSaver {
|
|||||||
File file = BinaryPlayerUtil.getFile(player.getUsername());
|
File file = BinaryPlayerUtil.getFile(player.getUsername());
|
||||||
|
|
||||||
try (DataOutputStream out = new DataOutputStream(new FileOutputStream(file))) {
|
try (DataOutputStream out = new DataOutputStream(new FileOutputStream(file))) {
|
||||||
// write credentials and privileges
|
|
||||||
StreamUtil.writeString(out, player.getUsername());
|
StreamUtil.writeString(out, player.getUsername());
|
||||||
StreamUtil.writeString(out, player.getCredentials().getPassword());
|
StreamUtil.writeString(out, player.getCredentials().getPassword());
|
||||||
out.writeByte(player.getPrivilegeLevel().toInteger());
|
out.writeByte(player.getPrivilegeLevel().toInteger());
|
||||||
out.writeByte(player.getMembershipStatus().getValue());
|
out.writeByte(player.getMembershipStatus().getValue());
|
||||||
|
|
||||||
// write settings
|
|
||||||
out.writeByte(player.getChatPrivacy().toInteger(true));
|
out.writeByte(player.getChatPrivacy().toInteger(true));
|
||||||
out.writeByte(player.getFriendPrivacy().toInteger(false));
|
out.writeByte(player.getFriendPrivacy().toInteger(false));
|
||||||
out.writeByte(player.getTradePrivacy().toInteger(false));
|
out.writeByte(player.getTradePrivacy().toInteger(false));
|
||||||
out.writeByte(player.getRunEnergy());
|
out.writeByte(player.getRunEnergy());
|
||||||
out.writeByte(player.getScreenBrightness().toInteger());
|
out.writeByte(player.getScreenBrightness().toInteger());
|
||||||
|
|
||||||
// write position
|
|
||||||
Position position = player.getPosition();
|
Position position = player.getPosition();
|
||||||
out.writeShort(position.getX());
|
out.writeShort(position.getX());
|
||||||
out.writeShort(position.getY());
|
out.writeShort(position.getY());
|
||||||
out.writeByte(position.getHeight());
|
out.writeByte(position.getHeight());
|
||||||
|
|
||||||
// write appearance
|
|
||||||
out.writeBoolean(player.isNew());
|
|
||||||
Appearance appearance = player.getAppearance();
|
Appearance appearance = player.getAppearance();
|
||||||
out.writeByte(appearance.getGender().toInteger());
|
out.writeByte(appearance.getGender().toInteger());
|
||||||
int[] style = appearance.getStyle();
|
int[] style = appearance.getStyle();
|
||||||
@@ -66,14 +60,11 @@ public final class BinaryPlayerSaver implements PlayerSaver {
|
|||||||
for (int color : colors) {
|
for (int color : colors) {
|
||||||
out.writeByte(color);
|
out.writeByte(color);
|
||||||
}
|
}
|
||||||
out.flush();
|
|
||||||
|
|
||||||
// write inventories
|
|
||||||
writeInventory(out, player.getInventory());
|
writeInventory(out, player.getInventory());
|
||||||
writeInventory(out, player.getEquipment());
|
writeInventory(out, player.getEquipment());
|
||||||
writeInventory(out, player.getBank());
|
writeInventory(out, player.getBank());
|
||||||
|
|
||||||
// write skills
|
|
||||||
SkillSet skills = player.getSkillSet();
|
SkillSet skills = player.getSkillSet();
|
||||||
out.writeByte(skills.size());
|
out.writeByte(skills.size());
|
||||||
for (int id = 0; id < skills.size(); id++) {
|
for (int id = 0; id < skills.size(); id++) {
|
||||||
@@ -95,47 +86,20 @@ public final class BinaryPlayerSaver implements PlayerSaver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Set<Entry<String, Attribute<?>>> attributes = player.getAttributes().entrySet();
|
Set<Entry<String, Attribute<?>>> 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());
|
out.writeInt(attributes.size());
|
||||||
|
|
||||||
for (Entry<String, Attribute<?>> entry : attributes) {
|
for (Entry<String, Attribute<?>> entry : attributes) {
|
||||||
String name = entry.getKey();
|
String name = entry.getKey();
|
||||||
StreamUtil.writeString(out, name);
|
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.
|
* Writes an inventory to the specified output stream.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -32,8 +32,8 @@ public final class BinaryPlayerUtil {
|
|||||||
* @return The file.
|
* @return The file.
|
||||||
*/
|
*/
|
||||||
public static File getFile(String username) {
|
public static File getFile(String username) {
|
||||||
username = NameUtil.decodeBase37(NameUtil.encodeBase37(username));
|
String filtered = NameUtil.decodeBase37(NameUtil.encodeBase37(username));
|
||||||
return new File(SAVED_GAMES_DIRECTORY, username + ".dat");
|
return new File(SAVED_GAMES_DIRECTORY, filtered + ".dat");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user