Remove the World singleton.

This commit is contained in:
Major-
2015-03-28 13:46:50 +00:00
parent 7cf31a2888
commit 3bd3ddd226
68 changed files with 620 additions and 323 deletions
+11 -29
View File
@@ -52,7 +52,6 @@ public final class Server {
SocketAddress http = new InetSocketAddress(NetworkConstants.HTTP_PORT);
SocketAddress jaggrab = new InetSocketAddress(NetworkConstants.JAGGRAB_PORT);
server.start();
server.bind(service, http, jaggrab);
logger.fine("Starting apollo took " + (System.currentTimeMillis() - start) + " ms.");
} catch (Throwable t) {
@@ -60,11 +59,6 @@ public final class Server {
}
}
/**
* The server's context.
*/
private ServerContext context;
/**
* The {@link ServerBootstrap} for the HTTP listener.
*/
@@ -85,11 +79,6 @@ public final class Server {
*/
private final EventLoopGroup loopGroup = new NioEventLoopGroup();
/**
* The service manager.
*/
private final ServiceManager serviceManager = new ServiceManager();
/**
* Creates the Apollo server.
*
@@ -109,13 +98,13 @@ public final class Server {
public void bind(SocketAddress serviceAddress, SocketAddress httpAddress, SocketAddress jagGrabAddress) {
try {
logger.fine("Binding service listener to address: " + serviceAddress + "...");
serviceBootstrap.bind(serviceAddress).sync();
serviceBootstrap.bind(serviceAddress).syncUninterruptibly();
logger.fine("Binding HTTP listener to address: " + httpAddress + "...");
httpBootstrap.bind(httpAddress).sync();
httpBootstrap.bind(httpAddress).syncUninterruptibly();
logger.fine("Binding JAGGRAB listener to address: " + jagGrabAddress + "...");
jagGrabBootstrap.bind(jagGrabAddress).sync();
jagGrabBootstrap.bind(jagGrabAddress).syncUninterruptibly();
} catch (Exception e) {
logger.log(Level.SEVERE, "Binding to a port failed: ensure apollo isn't already running.", e);
System.exit(1);
@@ -128,11 +117,9 @@ public final class Server {
* Initialises the server.
*
* @param releaseClassName The class name of the current active {@link Release}.
* @throws ClassNotFoundException If the release class could not be found.
* @throws IllegalAccessException If the release class could not be accessed.
* @throws InstantiationException If the release class could not be instantiated.
* @throws Exception If an error occurs.
*/
public void init(String releaseClassName) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
public void init(String releaseClassName) throws Exception {
Class<?> clazz = Class.forName(releaseClassName);
Release release = (Release) clazz.newInstance();
@@ -142,7 +129,9 @@ public final class Server {
httpBootstrap.group(loopGroup);
jagGrabBootstrap.group(loopGroup);
context = new ServerContext(release, serviceManager);
World world = new World();
ServiceManager serviceManager = new ServiceManager(world);
ServerContext context = new ServerContext(release, serviceManager);
ApolloHandler handler = new ApolloHandler(context);
ChannelInitializer<SocketChannel> serviceInitializer = new ServiceChannelInitializer(handler);
@@ -156,20 +145,13 @@ public final class Server {
ChannelInitializer<SocketChannel> jagGrabInitializer = new JagGrabChannelInitializer(handler);
jagGrabBootstrap.channel(NioServerSocketChannel.class);
jagGrabBootstrap.childHandler(jagGrabInitializer);
}
/**
* Starts the server.
*
* @throws Exception If an error occurs.
*/
public void start() throws Exception {
PluginManager manager = new PluginManager(new PluginContext(context));
PluginManager manager = new PluginManager(world, new PluginContext(context));
serviceManager.startAll();
int releaseNo = context.getRelease().getReleaseNumber();
int releaseNo = release.getReleaseNumber();
IndexedFileSystem fs = new IndexedFileSystem(Paths.get("data/fs", Integer.toString(releaseNo)), true);
World.getWorld().init(releaseNo, fs, manager);
world.init(releaseNo, fs, manager);
}
}
+17 -1
View File
@@ -1,17 +1,33 @@
package org.apollo;
import org.apollo.game.model.World;
/**
* Represents a service that the server provides.
* Represents a service that the server provides for a {@link World}.
*
* @author Graham
*/
public abstract class Service {
/**
* The World this Service is for.
*/
protected final World world;
/**
* The server context.
*/
private ServerContext context;
/**
* Creates the Service.
*
* @param world The {@link World} the Service is for.
*/
public Service(World world) {
this.world = world;
}
/**
* Gets the {@link ServerContext}.
*
+8 -7
View File
@@ -7,6 +7,7 @@ import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;
import org.apollo.game.model.World;
import org.apollo.util.xml.XmlNode;
import org.apollo.util.xml.XmlParser;
import org.xml.sax.SAXException;
@@ -31,12 +32,13 @@ public final class ServiceManager {
/**
* Creates and initializes the {@link ServiceManager}.
*
* @param world The {@link World} to create the {@link Service}s for.
* @throws IOException If there is an error reading from the xml file.
* @throws SAXException If there is an error parsing the xml file.
* @throws ReflectiveOperationException If there is an error accessing or creating services using reflection.
*/
public ServiceManager() throws IOException, SAXException, ReflectiveOperationException {
init();
public ServiceManager(World world) throws IOException, SAXException, ReflectiveOperationException {
init(world);
}
/**
@@ -53,14 +55,13 @@ public final class ServiceManager {
/**
* Initializes this service manager.
*
* @param world The {@link World} to create the {@link Service}s for.
* @throws SAXException If the service XML file could not be parsed.
* @throws IOException If the file could not be accessed.
* @throws IllegalAccessException If the service could not be accessed.
* @throws InstantiationException If the service could not be instantiated.
* @throws ClassNotFoundException If the service could not be found.
* @throws ReflectiveOperationException If the Service could not be created.
*/
@SuppressWarnings("unchecked")
private void init() throws SAXException, IOException, InstantiationException, IllegalAccessException, ClassNotFoundException {
private void init(World world) throws SAXException, IOException, ReflectiveOperationException {
logger.fine("Registering services...");
XmlParser parser = new XmlParser();
@@ -84,7 +85,7 @@ public final class ServiceManager {
}
Class<? extends Service> service = (Class<? extends Service>) Class.forName(child.getValue());
register((Class<Service>) service, service.newInstance());
register((Class<Service>) service, service.getConstructor(World.class).newInstance(world));
}
}
@@ -11,6 +11,7 @@ import java.util.function.Predicate;
import org.apollo.fs.IndexedFileSystem;
import org.apollo.fs.decoder.MapFileDecoder.MapDefinition;
import org.apollo.game.model.Position;
import org.apollo.game.model.World;
import org.apollo.game.model.area.Region;
import org.apollo.game.model.area.RegionRepository;
import org.apollo.game.model.area.collision.CollisionMatrix;
@@ -70,10 +71,11 @@ public final class GameObjectDecoder {
/**
* Decodes the GameObjects from their MapDefinitions.
*
* @param world The {@link World} containing the StaticGameObjects.
* @return The decoded objects.
* @throws IOException If there is an error decoding the {@link MapDefinition}s.
*/
public GameObject[] decode() throws IOException {
public GameObject[] decode(World world) throws IOException {
Map<Integer, MapDefinition> definitions = MapFileDecoder.decode(fs);
for (Entry<Integer, MapDefinition> entry : definitions.entrySet()) {
@@ -85,7 +87,7 @@ public final class GameObjectDecoder {
ByteBuffer objects = fs.getFile(4, definition.getObjectFile());
ByteBuffer decompressed = ByteBuffer.wrap(CompressionUtil.degzip(objects));
decodeObjects(decompressed, x, y);
decodeObjects(world, decompressed, x, y);
ByteBuffer terrain = fs.getFile(4, definition.getTerrainFile());
decompressed = ByteBuffer.wrap(CompressionUtil.degzip(terrain));
@@ -189,11 +191,12 @@ public final class GameObjectDecoder {
/**
* Decodes object data stored in the specified {@link ByteBuffer}.
*
* @param world The {@link World} containing the StaticGameObjects.
* @param buffer The ByteBuffer.
* @param x The x coordinate of the top left tile of the map file.
* @param y The y coordinate of the top left tile of the map file.
*/
private void decodeObjects(ByteBuffer buffer, int x, int y) {
private void decodeObjects(World world, ByteBuffer buffer, int x, int y) {
int id = -1;
int idOffset = BufferUtil.readSmart(buffer);
@@ -215,7 +218,7 @@ public final class GameObjectDecoder {
int orientation = attributes & 0x3;
Position position = new Position(x + localX, y + localY, height);
GameObject object = new StaticGameObject(id, position, type, orientation);
GameObject object = new StaticGameObject(world, id, position, type, orientation);
objects.add(object);
block(object, position);
+9 -12
View File
@@ -59,11 +59,13 @@ public final class GameService extends Service {
private ClientSynchronizer synchronizer;
/**
* Creates the game service.
* Creates the GameService.
*
* @param world The {@link World} the GameService is for.
* @throws Exception If an error occurs during initialization.
*/
public GameService() throws Exception {
public GameService(World world) throws Exception {
super(world);
init();
}
@@ -74,7 +76,7 @@ public final class GameService extends Service {
*/
public void finalizePlayerUnregistration(Player player) {
synchronized (this) {
World.getWorld().unregister(player);
world.unregister(player);
}
}
@@ -93,14 +95,12 @@ public final class GameService extends Service {
* @throws IOException If there is an error with the file (e.g. does not exist, cannot be read, does not contain
* valid nodes).
* @throws SAXException If there is an error parsing the file.
* @throws ClassNotFoundException If a message handler could not be found.
* @throws InstantiationException If a message handler could not be instantiated.
* @throws IllegalAccessException If a message handler could not be accessed.
* @throws ReflectiveOperationException If a MessageHandler could not be created.
*/
private void init() throws IOException, SAXException, ClassNotFoundException, InstantiationException, IllegalAccessException {
private void init() throws IOException, SAXException, ReflectiveOperationException {
try (InputStream is = new FileInputStream("data/messages.xml")) {
MessageHandlerChainParser chainGroupParser = new MessageHandlerChainParser(is);
chainGroup = chainGroupParser.parse();
chainGroup = chainGroupParser.parse(world);
}
try (InputStream is = new FileInputStream("data/synchronizer.xml")) {
@@ -127,7 +127,6 @@ public final class GameService extends Service {
public void pulse() {
synchronized (this) {
LoginService loginService = getContext().getService(LoginService.class);
World world = World.getWorld();
int unregistered = 0;
Player old;
@@ -144,7 +143,7 @@ public final class GameService extends Service {
}
world.pulse();
synchronizer.synchronize();
synchronizer.synchronize(world.getPlayerRepository(), world.getNpcRepository());
}
}
@@ -156,8 +155,6 @@ public final class GameService extends Service {
* @return A {@link RegistrationStatus}.
*/
public RegistrationStatus registerPlayer(Player player, GameSession session) {
World world = World.getWorld();
synchronized (this) {
RegistrationStatus status = world.register(player);
if (status == RegistrationStatus.OK) {
@@ -2,6 +2,7 @@ package org.apollo.game.command;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.apollo.game.model.entity.Player;
@@ -18,10 +19,12 @@ public final class CommandDispatcher {
private final Map<String, CommandListener> listeners = new HashMap<>();
/**
* Creates the command dispatcher and registers a listener for the credits command.
* Initialises this CommandDispatcher.
*
* @param authors The {@link Set} of plugin authors.
*/
public CommandDispatcher() {
listeners.put("credits", new CreditsCommandListener());
public void init(Set<String> authors) {
listeners.put("credits", new CreditsCommandListener(authors));
}
/**
@@ -4,9 +4,9 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.apollo.game.model.World;
import org.apollo.game.model.entity.Player;
import org.apollo.util.plugin.PluginManager;
import com.google.common.collect.ImmutableSet;
/**
* Implements a {@code ::credits} command that lists the authors of all plugins used in the server.
@@ -14,6 +14,20 @@ import org.apollo.util.plugin.PluginManager;
* @author Graham
*/
public final class CreditsCommandListener extends CommandListener {
/**
* The Set of authors.
*/
private final Set<String> authors;
/**
* Creates the CreditsCommandListener.
*
* @param authors The {@link Set} of authors.
*/
public CreditsCommandListener(Set<String> authors) {
this.authors = ImmutableSet.copyOf(authors);
}
/*
* If you are considering removing this command, please bear in mind that Apollo took several people thousands of
@@ -26,9 +40,6 @@ public final class CreditsCommandListener extends CommandListener {
@Override
public void execute(Player player, Command command) {
PluginManager mgr = World.getWorld().getPluginManager();
final Set<String> authors = mgr.getAuthors();
List<String> text = new ArrayList<>(12 + authors.size());
text.add("@dre@Apollo");
text.add("@dre@Introduction");
@@ -1,6 +1,7 @@
package org.apollo.game.message.handler;
import org.apollo.game.message.Message;
import org.apollo.game.model.World;
import org.apollo.game.model.entity.Player;
/**
@@ -11,6 +12,20 @@ import org.apollo.game.model.entity.Player;
*/
public abstract class MessageHandler<M extends Message> {
/**
* The World the Message occurred in.
*/
protected final World world;
/**
* Creates the MessageHandler.
*
* @param world The {@link World} the {@link Message} occurred in.
*/
public MessageHandler(World world) {
this.world = world;
}
/**
* Handles a message.
*
@@ -3,6 +3,7 @@ package org.apollo.game.message.handler.impl;
import org.apollo.game.message.handler.MessageHandler;
import org.apollo.game.message.handler.MessageHandlerContext;
import org.apollo.game.message.impl.ButtonMessage;
import org.apollo.game.model.World;
import org.apollo.game.model.entity.Player;
/**
@@ -12,6 +13,15 @@ import org.apollo.game.model.entity.Player;
*/
public final class BankButtonMessageHandler extends MessageHandler<ButtonMessage> {
/**
* Creates the BankButtonMessageHandler.
*
* @param world The {@link World} the {@link ButtonMessage} occurred in.
*/
public BankButtonMessageHandler(World world) {
super(world);
}
/**
* The withdraw as item button id.
*/
@@ -3,6 +3,7 @@ package org.apollo.game.message.handler.impl;
import org.apollo.game.message.handler.MessageHandler;
import org.apollo.game.message.handler.MessageHandlerContext;
import org.apollo.game.message.impl.ItemActionMessage;
import org.apollo.game.model.World;
import org.apollo.game.model.entity.Player;
import org.apollo.game.model.inter.EnterAmountListener;
import org.apollo.game.model.inter.bank.BankConstants;
@@ -41,21 +42,12 @@ public final class BankMessageHandler extends MessageHandler<ItemActionMessage>
}
/**
* Handles a deposit action.
*
* @param ctx The message handler context.
* @param player The player.
* @param message The message.
* Creates the BankMessageHandler.
*
* @param world The {@link World} the {@link ItemActionMessage} occurred in.
*/
private static void deposit(MessageHandlerContext ctx, Player player, ItemActionMessage message) {
int amount = optionToAmount(message.getOption());
if (amount == -1) {
EnterAmountListener listener = new BankDepositEnterAmountListener(player, message.getSlot(), message.getId());
player.getInterfaceSet().openEnterAmountDialogue(listener);
} else if (!BankUtils.deposit(player, message.getSlot(), message.getId(), amount)) {
ctx.breakHandlerChain();
}
public BankMessageHandler(World world) {
super(world);
}
@Override
@@ -69,6 +61,24 @@ public final class BankMessageHandler extends MessageHandler<ItemActionMessage>
}
}
/**
* Handles a deposit action.
*
* @param ctx The message handler context.
* @param player The player.
* @param message The message.
*/
private void deposit(MessageHandlerContext ctx, Player player, ItemActionMessage message) {
int amount = optionToAmount(message.getOption());
if (amount == -1) {
EnterAmountListener listener = new BankDepositEnterAmountListener(player, message.getSlot(), message.getId());
player.getInterfaceSet().openEnterAmountDialogue(listener);
} else if (!BankUtils.deposit(player, message.getSlot(), message.getId(), amount)) {
ctx.breakHandlerChain();
}
}
/**
* Handles a withdraw action.
*
@@ -76,7 +86,7 @@ public final class BankMessageHandler extends MessageHandler<ItemActionMessage>
* @param player The player.
* @param message The message.
*/
private static void withdraw(MessageHandlerContext ctx, Player player, ItemActionMessage message) {
private void withdraw(MessageHandlerContext ctx, Player player, ItemActionMessage message) {
int amount = optionToAmount(message.getOption());
if (amount == -1) {
@@ -3,6 +3,7 @@ package org.apollo.game.message.handler.impl;
import org.apollo.game.message.handler.MessageHandler;
import org.apollo.game.message.handler.MessageHandlerContext;
import org.apollo.game.message.impl.ChatMessage;
import org.apollo.game.model.World;
import org.apollo.game.model.entity.Player;
import org.apollo.game.sync.block.SynchronizationBlock;
@@ -13,6 +14,15 @@ import org.apollo.game.sync.block.SynchronizationBlock;
*/
public final class ChatMessageHandler extends MessageHandler<ChatMessage> {
/**
* Creates the ChatMessageHandler.
*
* @param world The {@link World} the {@link ChatMessage} occurred in.
*/
public ChatMessageHandler(World world) {
super(world);
}
@Override
public void handle(MessageHandlerContext ctx, Player player, ChatMessage message) {
player.getBlockSet().add(SynchronizationBlock.createChatBlock(player, message));
@@ -3,6 +3,7 @@ package org.apollo.game.message.handler.impl;
import org.apollo.game.message.handler.MessageHandler;
import org.apollo.game.message.handler.MessageHandlerContext;
import org.apollo.game.message.impl.ChatMessage;
import org.apollo.game.model.World;
import org.apollo.game.model.entity.Player;
/**
@@ -12,6 +13,15 @@ import org.apollo.game.model.entity.Player;
*/
public final class ChatVerificationHandler extends MessageHandler<ChatMessage> {
/**
* Creates the ChatVerificationHandler.
*
* @param world The {@link World} the {@link ChatMessage} occurred in.
*/
public ChatVerificationHandler(World world) {
super(world);
}
@Override
public void handle(MessageHandlerContext ctx, Player player, ChatMessage message) {
int color = message.getTextColor();
@@ -3,6 +3,7 @@ package org.apollo.game.message.handler.impl;
import org.apollo.game.message.handler.MessageHandler;
import org.apollo.game.message.handler.MessageHandlerContext;
import org.apollo.game.message.impl.ClosedInterfaceMessage;
import org.apollo.game.model.World;
import org.apollo.game.model.entity.Player;
/**
@@ -12,6 +13,15 @@ import org.apollo.game.model.entity.Player;
*/
public final class ClosedInterfaceMessageHandler extends MessageHandler<ClosedInterfaceMessage> {
/**
* Creates the ClosedInterfaceMessageHandler.
*
* @param world The {@link World} the {@link ClosedInterfaceMessage} occurred in.
*/
public ClosedInterfaceMessageHandler(World world) {
super(world);
}
@Override
public void handle(MessageHandlerContext ctx, Player player, ClosedInterfaceMessage message) {
player.getInterfaceSet().interfaceClosed();
@@ -1,6 +1,7 @@
package org.apollo.game.message.handler.impl;
import org.apollo.game.command.Command;
import org.apollo.game.message.Message;
import org.apollo.game.message.handler.MessageHandler;
import org.apollo.game.message.handler.MessageHandlerContext;
import org.apollo.game.message.impl.CommandMessage;
@@ -14,6 +15,15 @@ import org.apollo.game.model.entity.Player;
*/
public final class CommandMessageHandler extends MessageHandler<CommandMessage> {
/**
* Creates the CommandMessageHandler.
*
* @param world The {@link World} the {@link Message} occurred in.
*/
public CommandMessageHandler(World world) {
super(world);
}
@Override
public void handle(MessageHandlerContext ctx, Player player, CommandMessage message) {
String[] components = message.getCommand().split(" ");
@@ -23,7 +33,7 @@ public final class CommandMessageHandler extends MessageHandler<CommandMessage>
System.arraycopy(components, 1, arguments, 0, arguments.length);
Command command = new Command(name, arguments);
World.getWorld().getCommandDispatcher().dispatch(player, command);
world.getCommandDispatcher().dispatch(player, command);
}
}
@@ -3,6 +3,7 @@ package org.apollo.game.message.handler.impl;
import org.apollo.game.message.handler.MessageHandler;
import org.apollo.game.message.handler.MessageHandlerContext;
import org.apollo.game.message.impl.ButtonMessage;
import org.apollo.game.model.World;
import org.apollo.game.model.entity.Player;
import org.apollo.game.model.inter.InterfaceType;
@@ -14,12 +15,21 @@ import org.apollo.game.model.inter.InterfaceType;
*/
public final class DialogueButtonHandler extends MessageHandler<ButtonMessage> {
/**
* Creates the DialogueButtonHandler.
*
* @param world The {@link World} the {@link ButtonMessage} occurred in.
*/
public DialogueButtonHandler(World world) {
super(world);
}
@Override
public void handle(MessageHandlerContext ctx, Player player, ButtonMessage message) {
if (player.getInterfaceSet().contains(InterfaceType.DIALOGUE)) {
boolean breakChain = player.getInterfaceSet().buttonClicked(message.getWidgetId());
boolean terminate = player.getInterfaceSet().buttonClicked(message.getWidgetId());
if (breakChain) {
if (terminate) {
ctx.breakHandlerChain();
}
}
@@ -3,6 +3,7 @@ package org.apollo.game.message.handler.impl;
import org.apollo.game.message.handler.MessageHandler;
import org.apollo.game.message.handler.MessageHandlerContext;
import org.apollo.game.message.impl.DialogueContinueMessage;
import org.apollo.game.model.World;
import org.apollo.game.model.entity.Player;
import org.apollo.game.model.inter.InterfaceType;
@@ -13,6 +14,15 @@ import org.apollo.game.model.inter.InterfaceType;
*/
public final class DialogueContinueMessageHandler extends MessageHandler<DialogueContinueMessage> {
/**
* Creates the DialogueContinueMessageHandler.
*
* @param world The {@link World} the {@link DialogueContinueMessage} occurred in.
*/
public DialogueContinueMessageHandler(World world) {
super(world);
}
@Override
public void handle(MessageHandlerContext ctx, Player player, DialogueContinueMessage message) {
if (player.getInterfaceSet().contains(InterfaceType.DIALOGUE)) {
@@ -3,6 +3,7 @@ package org.apollo.game.message.handler.impl;
import org.apollo.game.message.handler.MessageHandler;
import org.apollo.game.message.handler.MessageHandlerContext;
import org.apollo.game.message.impl.EnteredAmountMessage;
import org.apollo.game.model.World;
import org.apollo.game.model.entity.Player;
/**
@@ -12,6 +13,15 @@ import org.apollo.game.model.entity.Player;
*/
public final class EnteredAmountMessageHandler extends MessageHandler<EnteredAmountMessage> {
/**
* Creates the EnteredAmountMessageHandler.
*
* @param world The {@link World} the {@link EnteredAmountMessage} occurred in.
*/
public EnteredAmountMessageHandler(World world) {
super(world);
}
@Override
public void handle(MessageHandlerContext ctx, Player player, EnteredAmountMessage message) {
player.getInterfaceSet().enteredAmount(message.getAmount());
@@ -4,6 +4,7 @@ import org.apollo.game.message.handler.MessageHandler;
import org.apollo.game.message.handler.MessageHandlerContext;
import org.apollo.game.message.impl.ItemOptionMessage;
import org.apollo.game.model.Item;
import org.apollo.game.model.World;
import org.apollo.game.model.def.EquipmentDefinition;
import org.apollo.game.model.entity.EquipmentConstants;
import org.apollo.game.model.entity.Player;
@@ -20,10 +21,24 @@ import org.apollo.util.LanguageUtil;
* @author Ryley
*/
public final class EquipItemHandler extends MessageHandler<ItemOptionMessage> {
/**
* The option used when equipping an item.
*/
private static final int EQUIP_OPTION = 2;
/**
* Creates the EquipItemHandler.
*
* @param world The {@link World} the {@link ItemOptionMessage} occurred in.
*/
public EquipItemHandler(World world) {
super(world);
}
@Override
public void handle(MessageHandlerContext ctx, Player player, ItemOptionMessage message) {
if (message.getOption() != 2 || message.getInterfaceId() != SynchronizationInventoryListener.INVENTORY_ID) {
if (message.getOption() != EQUIP_OPTION || message.getInterfaceId() != SynchronizationInventoryListener.INVENTORY_ID) {
return;
}
@@ -82,7 +97,8 @@ public final class EquipItemHandler extends MessageHandler<ItemOptionMessage> {
return;
}
if (definition.getSlot() == EquipmentConstants.SHIELD && weapon != null && EquipmentDefinition.lookup(weapon.getId()).isTwoHanded()) {
if (definition.getSlot() == EquipmentConstants.SHIELD && weapon != null
&& EquipmentDefinition.lookup(weapon.getId()).isTwoHanded()) {
equipment.set(EquipmentConstants.SHIELD, inventory.reset(inventorySlot));
inventory.add(equipment.reset(EquipmentConstants.WEAPON));
return;
@@ -4,6 +4,7 @@ import org.apollo.game.message.handler.MessageHandler;
import org.apollo.game.message.handler.MessageHandlerContext;
import org.apollo.game.message.impl.ItemOnItemMessage;
import org.apollo.game.model.Item;
import org.apollo.game.model.World;
import org.apollo.game.model.entity.Player;
import org.apollo.game.model.inter.bank.BankConstants;
import org.apollo.game.model.inv.Inventory;
@@ -16,6 +17,15 @@ import org.apollo.game.model.inv.SynchronizationInventoryListener;
*/
public final class ItemOnItemVerificationHandler extends MessageHandler<ItemOnItemMessage> {
/**
* Creates the ItemOnItemVerificationHandler.
*
* @param world The {@link World} the {@link ItemOnItemMessage} occurred in.
*/
public ItemOnItemVerificationHandler(World world) {
super(world);
}
@Override
public void handle(MessageHandlerContext ctx, Player player, ItemOnItemMessage message) {
Inventory inventory;
@@ -4,6 +4,7 @@ import org.apollo.game.message.handler.MessageHandler;
import org.apollo.game.message.handler.MessageHandlerContext;
import org.apollo.game.message.impl.ItemOnObjectMessage;
import org.apollo.game.model.Item;
import org.apollo.game.model.World;
import org.apollo.game.model.entity.Player;
import org.apollo.game.model.inter.bank.BankConstants;
import org.apollo.game.model.inv.Inventory;
@@ -16,9 +17,19 @@ import org.apollo.game.model.inv.SynchronizationInventoryListener;
*/
public final class ItemOnObjectVerificationHandler extends MessageHandler<ItemOnObjectMessage> {
/**
* Creates the ItemOnObjectVerificationHandler.
*
* @param world The {@link World} the {@link ItemOnObjectMessage} occurred in.
*/
public ItemOnObjectVerificationHandler(World world) {
super(world);
}
@Override
public void handle(MessageHandlerContext ctx, Player player, ItemOnObjectMessage message) {
if (message.getInterfaceId() != SynchronizationInventoryListener.INVENTORY_ID && message.getInterfaceId() != BankConstants.SIDEBAR_INVENTORY_ID) {
if (message.getInterfaceId() != SynchronizationInventoryListener.INVENTORY_ID
&& message.getInterfaceId() != BankConstants.SIDEBAR_INVENTORY_ID) {
ctx.breakHandlerChain();
return;
}
@@ -7,6 +7,7 @@ import org.apollo.game.message.handler.MessageHandler;
import org.apollo.game.message.handler.MessageHandlerContext;
import org.apollo.game.message.impl.InventoryItemMessage;
import org.apollo.game.model.Item;
import org.apollo.game.model.World;
import org.apollo.game.model.entity.Player;
import org.apollo.game.model.inter.bank.BankConstants;
import org.apollo.game.model.inv.Inventory;
@@ -20,6 +21,15 @@ import org.apollo.game.model.inv.SynchronizationInventoryListener;
*/
public final class ItemVerificationHandler extends MessageHandler<InventoryItemMessage> {
/**
* Creates the ItemVerificationHandler.
*
* @param world The {@link World} the {@link InventoryItemMessage} occurred in.
*/
public ItemVerificationHandler(World world) {
super(world);
}
/**
* A supplier for an {@link Inventory}.
*
@@ -18,13 +18,18 @@ import org.apollo.util.MobRepository;
public final class NpcActionVerificationHandler extends MessageHandler<NpcActionMessage> {
/**
* The world's npc repository.
* Creates the NpcActionVerificationHandler.
*
* @param world The {@link World} the {@link NpcActionMessage} occurred in.
*/
private final MobRepository<Npc> repository = World.getWorld().getNpcRepository();
public NpcActionVerificationHandler(World world) {
super(world);
}
@Override
public void handle(MessageHandlerContext ctx, Player player, NpcActionMessage message) {
int index = message.getIndex();
MobRepository<Npc> repository = world.getNpcRepository();
if (index < 0 || index >= repository.capacity()) {
ctx.breakHandlerChain();
@@ -9,7 +9,6 @@ import org.apollo.game.message.impl.ObjectActionMessage;
import org.apollo.game.model.Position;
import org.apollo.game.model.World;
import org.apollo.game.model.area.Region;
import org.apollo.game.model.area.RegionRepository;
import org.apollo.game.model.def.ObjectDefinition;
import org.apollo.game.model.entity.Entity.EntityType;
import org.apollo.game.model.entity.Player;
@@ -23,9 +22,24 @@ import org.apollo.game.model.entity.obj.GameObject;
public final class ObjectActionVerificationHandler extends MessageHandler<ObjectActionMessage> {
/**
* The world's RegionRepository.
* Indicates whether or not the {@link List} of {@link GameObject}s contains the object with the specified id.
*
* @param id The id of the object.
* @param objects The list of objects.
* @return {@code true} if the list does contain the object with the specified id, otherwise {@code false}.
*/
private final RegionRepository repository = World.getWorld().getRegionRepository();
private static boolean containsObject(int id, Set<GameObject> objects) {
return objects.stream().anyMatch(object -> object.getId() == id);
}
/**
* Creates the ObjectActionVerificationHandler.
*
* @param world The {@link World} the {@link ObjectActionMessage} occurred in.
*/
public ObjectActionVerificationHandler(World world) {
super(world);
}
@Override
public void handle(MessageHandlerContext ctx, Player player, ObjectActionMessage message) {
@@ -34,10 +48,9 @@ public final class ObjectActionVerificationHandler extends MessageHandler<Object
ctx.breakHandlerChain();
return;
}
Position position = message.getPosition();
Region region = repository.fromPosition(position);
Region region = world.getRegionRepository().fromPosition(position);
Set<GameObject> objects = region.getEntities(position, EntityType.STATIC_OBJECT, EntityType.DYNAMIC_OBJECT);
if (!player.getPosition().isWithinDistance(position, 15) || !containsObject(id, objects)) {
@@ -52,15 +65,4 @@ public final class ObjectActionVerificationHandler extends MessageHandler<Object
}
}
/**
* Indicates whether or not the {@link List} of {@link GameObject}s contains the object with the specified id.
*
* @param id The id of the object.
* @param objects The list of objects.
* @return {@code true} if the list does contain the object with the specified id, otherwise {@code false}.
*/
private static boolean containsObject(int id, Set<GameObject> objects) {
return objects.stream().anyMatch(object -> object.getId() == id);
}
}
@@ -15,13 +15,18 @@ import org.apollo.util.MobRepository;
public final class PlayerActionVerificationHandler extends MessageHandler<PlayerActionMessage> {
/**
* The world's player repository.
* Creates the PlayerActionVerificationHandler.
*
* @param world The {@link World} the {@link PlayerActionMessage} occurred in.
*/
private final MobRepository<Player> repository = World.getWorld().getPlayerRepository();
public PlayerActionVerificationHandler(World world) {
super(world);
}
@Override
public void handle(MessageHandlerContext ctx, Player player, PlayerActionMessage message) {
int index = message.getIndex();
MobRepository<Player> repository = world.getPlayerRepository();
if (index < 0 || index >= repository.capacity()) {
ctx.breakHandlerChain();
@@ -4,6 +4,7 @@ import org.apollo.game.message.handler.MessageHandler;
import org.apollo.game.message.handler.MessageHandlerContext;
import org.apollo.game.message.impl.CloseInterfaceMessage;
import org.apollo.game.message.impl.PlayerDesignMessage;
import org.apollo.game.model.World;
import org.apollo.game.model.entity.Player;
/**
@@ -13,6 +14,15 @@ import org.apollo.game.model.entity.Player;
*/
public final class PlayerDesignMessageHandler extends MessageHandler<PlayerDesignMessage> {
/**
* Creates the PlayerDesignMessageHandler.
*
* @param world The {@link World} the {@link PlayerDesignMessage} occurred in.
*/
public PlayerDesignMessageHandler(World world) {
super(world);
}
@Override
public void handle(MessageHandlerContext ctx, Player player, PlayerDesignMessage message) {
player.setAppearance(message.getAppearance());
@@ -4,6 +4,7 @@ import org.apollo.game.message.handler.MessageHandler;
import org.apollo.game.message.handler.MessageHandlerContext;
import org.apollo.game.message.impl.PlayerDesignMessage;
import org.apollo.game.model.Appearance;
import org.apollo.game.model.World;
import org.apollo.game.model.entity.Player;
import org.apollo.game.model.entity.setting.Gender;
@@ -14,6 +15,15 @@ import org.apollo.game.model.entity.setting.Gender;
*/
public final class PlayerDesignVerificationHandler extends MessageHandler<PlayerDesignMessage> {
/**
* Creates the PlayerDesignVerificationHandler.
*
* @param world The {@link World} the {@link PlayerDesignMessage} occurred in.
*/
public PlayerDesignVerificationHandler(World world) {
super(world);
}
@Override
public void handle(MessageHandlerContext ctx, Player player, PlayerDesignMessage message) {
if (!valid(message.getAppearance())) {
@@ -27,7 +37,7 @@ public final class PlayerDesignVerificationHandler extends MessageHandler<Player
* @param appearance The appearance combination.
* @return {@code true} if so, {@code false} if not.
*/
private static boolean valid(Appearance appearance) {
private boolean valid(Appearance appearance) {
int[] colors = appearance.getColors();
int[] maxColors = new int[] { 11, 15, 15, 5, 7 };
@@ -53,7 +63,7 @@ public final class PlayerDesignVerificationHandler extends MessageHandler<Player
* @param appearance The appearance combination.
* @return {@code true} if so, {@code false} if not.
*/
private static boolean validFemaleStyle(Appearance appearance) {
private boolean validFemaleStyle(Appearance appearance) {
int[] styles = appearance.getStyle();
int[] minStyles = new int[] { 45, 255, 56, 61, 67, 70, 79 };
int[] maxStyles = new int[] { 54, 255, 60, 65, 68, 77, 80 };
@@ -73,7 +83,7 @@ public final class PlayerDesignVerificationHandler extends MessageHandler<Player
* @param appearance The appearance combination.
* @return {@code true} if so, {@code false} if not.
*/
private static boolean validMaleStyle(Appearance appearance) {
private boolean validMaleStyle(Appearance appearance) {
int[] styles = appearance.getStyle();
int[] minStyles = new int[] { 0, 10, 18, 26, 33, 36, 42 };
int[] maxStyles = new int[] { 8, 17, 25, 31, 34, 40, 43 };
@@ -4,6 +4,7 @@ import org.apollo.game.message.handler.MessageHandler;
import org.apollo.game.message.handler.MessageHandlerContext;
import org.apollo.game.message.impl.ItemActionMessage;
import org.apollo.game.model.Item;
import org.apollo.game.model.World;
import org.apollo.game.model.entity.Player;
import org.apollo.game.model.inv.Inventory;
import org.apollo.game.model.inv.SynchronizationInventoryListener;
@@ -16,6 +17,15 @@ import org.apollo.game.model.inv.SynchronizationInventoryListener;
*/
public final class RemoveEquippedItemHandler extends MessageHandler<ItemActionMessage> {
/**
* Creates the RemoveEquippedItemHandler.
*
* @param world The {@link World} the {@link ItemActionMessage} occurred in.
*/
public RemoveEquippedItemHandler(World world) {
super(world);
}
@Override
public void handle(MessageHandlerContext ctx, Player player, ItemActionMessage message) {
if (message.getOption() == 1 && message.getInterfaceId() == SynchronizationInventoryListener.EQUIPMENT_ID) {
@@ -3,6 +3,7 @@ package org.apollo.game.message.handler.impl;
import org.apollo.game.message.handler.MessageHandler;
import org.apollo.game.message.handler.MessageHandlerContext;
import org.apollo.game.message.impl.SwitchItemMessage;
import org.apollo.game.model.World;
import org.apollo.game.model.entity.Player;
import org.apollo.game.model.inter.bank.BankConstants;
import org.apollo.game.model.inv.Inventory;
@@ -16,6 +17,15 @@ import org.apollo.game.model.inv.SynchronizationInventoryListener;
*/
public final class SwitchItemMessageHandler extends MessageHandler<SwitchItemMessage> {
/**
* Creates the SwitchItemMessageHandler.
*
* @param world The {@link World} the {@link SwitchItemMessage} occurred in.
*/
public SwitchItemMessageHandler(World world) {
super(world);
}
@Override
public void handle(MessageHandlerContext ctx, Player player, SwitchItemMessage message) {
Inventory inventory;
@@ -37,9 +47,10 @@ public final class SwitchItemMessageHandler extends MessageHandler<SwitchItemMes
return; // not a known inventory, ignore
}
if (message.getOldSlot() >= 0 && message.getNewSlot() >= 0 && message.getOldSlot() < inventory.capacity() && message.getNewSlot() < inventory.capacity()) {
int old = message.getOldSlot(), next = message.getNewSlot();
if (old >= 0 && next >= 0 && old < inventory.capacity() && next < inventory.capacity()) {
// events must be fired for it to work if a sidebar inventory overlay is used
inventory.swap(insertPermitted && message.isInserting(), message.getOldSlot(), message.getNewSlot());
inventory.swap(insertPermitted && message.isInserting(), old, next);
}
}
@@ -4,6 +4,7 @@ import org.apollo.game.message.handler.MessageHandler;
import org.apollo.game.message.handler.MessageHandlerContext;
import org.apollo.game.message.impl.WalkMessage;
import org.apollo.game.model.Position;
import org.apollo.game.model.World;
import org.apollo.game.model.entity.Player;
import org.apollo.game.model.entity.WalkingQueue;
@@ -14,6 +15,15 @@ import org.apollo.game.model.entity.WalkingQueue;
*/
public final class WalkMessageHandler extends MessageHandler<WalkMessage> {
/**
* Creates the WalkMessageHandler.
*
* @param world The {@link World} the {@link WalkMessage} occurred in.
*/
public WalkMessageHandler(World world) {
super(world);
}
@Override
public void handle(MessageHandlerContext ctx, Player player, WalkMessage message) {
WalkingQueue queue = player.getWalkingQueue();
@@ -2,6 +2,7 @@ package org.apollo.game.message.impl;
import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.OptionalInt;
import org.apollo.game.message.Message;
import org.apollo.game.model.Position;
@@ -62,7 +63,7 @@ public final class HintIconMessage extends Message {
* @return The HintIconMessage.
*/
public static HintIconMessage forNpc(int index) {
return new HintIconMessage(Type.NPC, Optional.of(index), Optional.empty());
return new HintIconMessage(Type.NPC, OptionalInt.of(index), Optional.empty());
}
/**
@@ -72,7 +73,7 @@ public final class HintIconMessage extends Message {
* @return The HintIconMessage.
*/
public static HintIconMessage forPlayer(int index) {
return new HintIconMessage(Type.PLAYER, Optional.of(index), Optional.empty());
return new HintIconMessage(Type.PLAYER, OptionalInt.of(index), Optional.empty());
}
/**
@@ -96,7 +97,7 @@ public final class HintIconMessage extends Message {
/**
* The index of the Mob, if applicable.
*/
private final Optional<Integer> index;
private final OptionalInt index;
/**
* The Position of the tile, if applicable.
@@ -115,7 +116,7 @@ public final class HintIconMessage extends Message {
* @param index The index of the Mob, if applicable.
* @param position The Position of the tile, if applicable.
*/
private HintIconMessage(Type type, Optional<Integer> index, Optional<Position> position) {
private HintIconMessage(Type type, OptionalInt index, Optional<Position> position) {
this.type = type;
this.index = index;
this.position = position;
@@ -128,7 +129,7 @@ public final class HintIconMessage extends Message {
* @throws NoSuchElementException If no index is available for this HintIcon.
*/
public int getIndex() {
return index.get();
return index.getAsInt();
}
/**
+6 -19
View File
@@ -23,9 +23,9 @@ import org.apollo.game.model.def.NpcDefinition;
import org.apollo.game.model.def.ObjectDefinition;
import org.apollo.game.model.entity.Entity;
import org.apollo.game.model.entity.Entity.EntityType;
import org.apollo.game.model.entity.obj.GameObject;
import org.apollo.game.model.entity.Npc;
import org.apollo.game.model.entity.Player;
import org.apollo.game.model.entity.obj.GameObject;
import org.apollo.game.model.event.Event;
import org.apollo.game.model.event.EventListener;
import org.apollo.game.model.event.EventListenerChainSet;
@@ -77,24 +77,10 @@ public final class World {
*/
private static final Logger logger = Logger.getLogger(World.class.getName());
/**
* The world.
*/
private static final World world = new World();
/**
* Gets the world.
*
* @return The world.
*/
public static World getWorld() {
return world;
}
/**
* The command dispatcher.
*/
private final CommandDispatcher commandDispatcher = new CommandDispatcher();
private CommandDispatcher commandDispatcher = new CommandDispatcher();
/**
* The EventListenerChainSet for this World.
@@ -144,7 +130,7 @@ public final class World {
/**
* Creates the world.
*/
private World() {
public World() {
}
@@ -247,14 +233,15 @@ public final class World {
logger.fine("Loaded " + objectDefs.length + " object definitions.");
GameObjectDecoder staticDecoder = new GameObjectDecoder(fs, regions);
GameObject[] objects = staticDecoder.decode();
GameObject[] objects = staticDecoder.decode(this);
placeEntities(objects);
logger.fine("Loaded " + objects.length + " static objects.");
npcMovement = new NpcMovementTask(); // Must be exactly here because of ordering issues.
npcMovement = new NpcMovementTask(regions); // Must be exactly here because of ordering issues.
scheduler.schedule(npcMovement);
manager.start();
commandDispatcher.init(manager.getAuthors());
pluginManager = manager;
}
+33 -16
View File
@@ -1,6 +1,7 @@
package org.apollo.game.model.entity;
import org.apollo.game.model.Position;
import org.apollo.game.model.World;
import org.apollo.game.model.area.EntityUpdateType;
import org.apollo.game.model.area.Region;
import org.apollo.game.model.area.update.UpdateOperation;
@@ -17,21 +18,16 @@ public abstract class Entity {
*/
public enum EntityType {
/**
* An Item that is positioned on the ground.
*/
GROUND_ITEM,
/**
* A GameObject that is loaded statically (i.e. from the game resources) at start-up.
*/
STATIC_OBJECT,
/**
* A GameObject that is loaded dynamically, usually for specific Players.
*/
DYNAMIC_OBJECT,
/**
* An Item that is positioned on the ground.
*/
GROUND_ITEM,
/**
* An Npc.
*/
@@ -45,7 +41,12 @@ public abstract class Entity {
/**
* A projectile (e.g. an arrow).
*/
PROJECTILE;
PROJECTILE,
/**
* A GameObject that is loaded statically (i.e. from the game resources) at start-up.
*/
STATIC_OBJECT;
/**
* Returns whether or not this EntityType is for a Mob.
@@ -59,16 +60,23 @@ public abstract class Entity {
}
/**
* The position of this entity.
* The Position of this Entity.
*/
protected Position position;
/**
* Creates a new entity with the specified position.
*
* @param position The position.
* The World containing this Entity.
*/
public Entity(Position position) {
protected final World world;
/**
* Creates the Entity.
*
* @param world The {@link World} containing the Entity.
* @param position The {@link Position} of the Entity.
*/
public Entity(World world, Position position) {
this.world = world;
this.position = position;
}
@@ -91,6 +99,15 @@ public abstract class Entity {
return position;
}
/**
* Gets the {@link World} this Entity is in.
*
* @return The World.
*/
public World getWorld() {
return world;
}
@Override
public abstract int hashCode();
@@ -2,8 +2,9 @@ package org.apollo.game.model.entity;
import org.apollo.game.model.Item;
import org.apollo.game.model.Position;
import org.apollo.game.model.area.Region;
import org.apollo.game.model.World;
import org.apollo.game.model.area.EntityUpdateType;
import org.apollo.game.model.area.Region;
import org.apollo.game.model.area.update.ItemUpdateOperation;
import org.apollo.game.model.area.update.UpdateOperation;
@@ -17,24 +18,26 @@ public final class GroundItem extends Entity {
/**
* Creates a new GroundItem.
*
* @param world The {@link World} containing the GroundItem.
* @param position The {@link Position} of the Item.
* @param item The Item displayed on the ground.
* @return The GroundItem.
*/
public static GroundItem create(Position position, Item item) {
return new GroundItem(position, item, -1);
public static GroundItem create(World world, Position position, Item item) {
return new GroundItem(world, position, item, -1);
}
/**
* Creates a new dropped GroundItem.
*
* @param world The {@link World} containing the GroundItem.
* @param position The {@link Position} of the Item.
* @param item The Item displayed on the ground.
* @param owner The the {@link Player} who dropped this GroundItem.
* @return The GroundItem.
*/
public static GroundItem dropped(Position position, Item item, Player owner) {
return new GroundItem(position, item, owner.getIndex());
public static GroundItem dropped(World world, Position position, Item item, Player owner) {
return new GroundItem(world, position, item, owner.getIndex());
}
/**
@@ -49,13 +52,14 @@ public final class GroundItem extends Entity {
/**
* Creates the GroundItem.
*
* @param position The {@link Position} of the Item.
*
* @param world The {@link World} containing the GroundItem.
* @param position The {@link Position} of the GroundItem.
* @param item The Item displayed on the ground.
* @param index The index of the {@link Player} who dropped this GroundItem.
*/
private GroundItem(Position position, Item item, int index) {
super(position);
private GroundItem(World world, Position position, Item item, int index) {
super(world, position);
this.item = item;
this.index = index;
}
+15 -13
View File
@@ -116,22 +116,24 @@ public abstract class Mob extends Entity {
private transient boolean teleporting = false;
/**
* Creates the mob with the specified initial {@link Position}.
* Creates the Mob.
*
* @param position The position.
* @param world The {@link World} containing the Mob
* @param position The {@link Position} of the Mob.
*/
public Mob(Position position) {
this(position, null);
public Mob(World world, Position position) {
this(world, position, null);
}
/**
* Creates the mob.
* Creates the Mob.
*
* @param position The initial position.
* @param definition The {@link NpcDefinition}.
* @param world The {@link World} containing the Mob
* @param position The {@link Position} of the Mob.
* @param definition The {@link NpcDefinition} of the Mob.
*/
public Mob(Position position, NpcDefinition definition) {
super(position);
public Mob(World world, Position position, NpcDefinition definition) {
super(world, position);
this.definition = Optional.ofNullable(definition);
init();
@@ -435,9 +437,9 @@ public abstract class Mob extends Entity {
* @param position The Position.
*/
public final void setPosition(Position position) {
if (World.getWorld().submit(new MobPositionUpdateEvent(this, position))) {
if (world.submit(new MobPositionUpdateEvent(this, position))) {
Position old = this.position;
RegionRepository repository = World.getWorld().getRegionRepository();
RegionRepository repository = world.getRegionRepository();
Region current = repository.fromPosition(old), next = repository.fromPosition(position);
current.removeEntity(this);
@@ -482,7 +484,7 @@ public abstract class Mob extends Entity {
}
this.action = action;
return World.getWorld().schedule(action);
return world.schedule(action);
}
/**
@@ -541,7 +543,7 @@ public abstract class Mob extends Entity {
* Initialises this mob.
*/
private void init() {
World.getWorld().schedule(new SkillNormalizationTask(this));
world.schedule(new SkillNormalizationTask(this));
}
}
+9 -6
View File
@@ -3,6 +3,7 @@ package org.apollo.game.model.entity;
import java.util.Optional;
import org.apollo.game.model.Position;
import org.apollo.game.model.World;
import org.apollo.game.model.def.NpcDefinition;
import org.apollo.game.sync.block.SynchronizationBlock;
@@ -22,24 +23,26 @@ public final class Npc extends Mob {
private Optional<Position[]> boundaries;
/**
* Creates a new Npc with the specified id and {@link Position}.
* Creates the Npc.
*
* @param world The {@link World} containing the Npc.
* @param id The id.
* @param position The position.
*/
public Npc(int id, Position position) {
this(position, NpcDefinition.lookup(id), null);
public Npc(World world, int id, Position position) {
this(world, position, NpcDefinition.lookup(id), null);
}
/**
* Creates a new Npc with the specified {@link NpcDefinition} and {@link Position}.
* Creates the Npc.
*
* @param world The {@link World} containing the Npc.
* @param position The Position.
* @param definition The NpcDefinition.
* @param boundaries The boundary Positions.
*/
public Npc(Position position, NpcDefinition definition, Position[] boundaries) {
super(position, definition);
public Npc(World world, Position position, NpcDefinition definition, Position[] boundaries) {
super(world, position, definition);
this.boundaries = Optional.ofNullable(boundaries);
}
+6 -6
View File
@@ -195,13 +195,14 @@ public final class Player extends Mob {
private transient int worldId = 1;
/**
* Creates the {@link Player}.
* Creates the Player.
*
* @param world The {@link World} containing the Player.
* @param credentials The player's credentials.
* @param position The initial position.
*/
public Player(PlayerCredentials credentials, Position position) {
super(position);
public Player(World world, PlayerCredentials credentials, Position position) {
super(world, position);
this.credentials = credentials;
init();
@@ -597,7 +598,7 @@ public final class Player extends Mob {
* Logs the player out, if possible.
*/
public void logout() {
if (World.getWorld().submit(new LogoutEvent(this))) {
if (world.submit(new LogoutEvent(this))) {
send(new LogoutMessage());
}
}
@@ -698,7 +699,7 @@ public final class Player extends Mob {
bank.forceRefresh();
skillSet.forceRefresh();
World.getWorld().submit(new LoginEvent(this));
world.submit(new LoginEvent(this));
}
/**
@@ -747,7 +748,6 @@ public final class Player extends Mob {
send(new IgnoreListMessage(ignores));
}
World world = World.getWorld();
for (String username : friends) {
int worldId = world.isPlayerOnline(username) ? world.getPlayer(username).worldId : 0;
send(new SendFriendMessage(username, worldId));
@@ -5,6 +5,7 @@ import java.util.HashSet;
import java.util.Set;
import org.apollo.game.model.Position;
import org.apollo.game.model.World;
import org.apollo.game.model.entity.Player;
/**
@@ -31,7 +32,7 @@ public final class DynamicGameObject extends GameObject {
@Override
public boolean equals(Object obj) {
if (obj instanceof WeakPlayerReference) {
WeakPlayerReference other = (WeakPlayerReference) obj;
WeakPlayerReference other = (WeakPlayerReference) obj; // TODO need to have a reference queue
Player player = get();
return player != null && player.equals(other.get());
@@ -51,27 +52,29 @@ public final class DynamicGameObject extends GameObject {
/**
* Creates a DynamicGameObject that is visible only to {@link Player}s specified later.
*
* @param world The {@link World} containing the DynamicGameObject.
* @param id The id of the DynamicGameObject
* @param position The {@link Position} of the DynamicGameObject.
* @param type The type of the DynamicGameObject.
* @param orientation The orientation of the DynamicGameObject.
* @return The DynamicGameObject.
*/
public static DynamicGameObject createLocal(int id, Position position, int type, int orientation) {
return new DynamicGameObject(id, position, type, orientation, false);
public static DynamicGameObject createLocal(World world, int id, Position position, int type, int orientation) {
return new DynamicGameObject(world, id, position, type, orientation, false);
}
/**
* Creates a DynamicGameObject that is always visible.
*
* @param world The {@link World} containing the DynamicGameObject.
* @param id The id of the DynamicGameObject
* @param position The {@link Position} of the DynamicGameObject.
* @param type The type of the DynamicGameObject.
* @param orientation The orientation of the DynamicGameObject.
* @return The DynamicGameObject.
*/
public static DynamicGameObject createPublic(int id, Position position, int type, int orientation) {
return new DynamicGameObject(id, position, type, orientation, true);
public static DynamicGameObject createPublic(World world, int id, Position position, int type, int orientation) {
return new DynamicGameObject(world, id, position, type, orientation, true);
}
/**
@@ -87,14 +90,15 @@ public final class DynamicGameObject extends GameObject {
/**
* Creates the DynamicGameObject.
*
* @param world The {@link World} containing the DynamicGameObject.
* @param id The id of the DynamicGameObject
* @param position The {@link Position} of the DynamicGameObject.
* @param type The type of the DynamicGameObject.
* @param orientation The orientation of the DynamicGameObject.
* @param alwaysVisible The flag indicates whether or not this DynamicGameObject is visible to every player.
*/
private DynamicGameObject(int id, Position position, int type, int orientation, boolean alwaysVisible) {
super(id, position, type, orientation);
private DynamicGameObject(World world, int id, Position position, int type, int orientation, boolean alwaysVisible) {
super(world, id, position, type, orientation);
this.alwaysVisible = alwaysVisible;
}
@@ -126,7 +130,7 @@ public final class DynamicGameObject extends GameObject {
}
@Override
public boolean viewableBy(Player player) {
public boolean viewableBy(Player player, World world) {
return alwaysVisible || players.contains(new WeakPlayerReference(player));
}
@@ -1,6 +1,7 @@
package org.apollo.game.model.entity.obj;
import org.apollo.game.model.Position;
import org.apollo.game.model.World;
import org.apollo.game.model.area.EntityUpdateType;
import org.apollo.game.model.area.Region;
import org.apollo.game.model.area.update.ObjectUpdateOperation;
@@ -26,13 +27,14 @@ public abstract class GameObject extends Entity {
/**
* Creates the GameObject.
*
* @param world The {@link World} containing the GameObject.
* @param id The id of the GameObject
* @param position The {@link Position} of the GameObject.
* @param type The type of the GameObject.
* @param orientation The orientation of the GameObject.
*/
public GameObject(int id, Position position, int type, int orientation) {
super(position);
public GameObject(World world, int id, Position position, int type, int orientation) {
super(world, position);
this.packed = id << 8 | (type & 0x3F) << 2 | orientation & 0x3;
}
@@ -102,8 +104,9 @@ public abstract class GameObject extends Entity {
* Returns whether or not this GameObject can be seen by the specified {@link Player}.
*
* @param player The Player.
* @param world The {@link World} containing the GameObject.
* @return {@code true} if the Player can see this GameObject, {@code false} if not.
*/
public abstract boolean viewableBy(Player player);
public abstract boolean viewableBy(Player player, World world);
}
@@ -16,13 +16,14 @@ public final class StaticGameObject extends GameObject {
/**
* Creates the StaticGameObject.
*
* @param world The {@link World} containing the StaticGameObject.
* @param id The id of the StaticGameObject
* @param position The {@link Position} of the StaticGameObject.
* @param type The type code of the StaticGameObject.
* @param orientation The orientation of the StaticGameObject.
*/
public StaticGameObject(int id, Position position, int type, int orientation) {
super(id, position, type, orientation);
public StaticGameObject(World world, int id, Position position, int type, int orientation) {
super(world, id, position, type, orientation);
}
@Override
@@ -31,8 +32,8 @@ public final class StaticGameObject extends GameObject {
}
@Override
public boolean viewableBy(Player player) {
RegionRepository repository = World.getWorld().getRegionRepository();
public boolean viewableBy(Player player, World world) {
RegionRepository repository = world.getRegionRepository();
RegionCoordinates coordinates = position.getRegionCoordinates();
return repository.get(coordinates).contains(this);
@@ -10,6 +10,7 @@ import java.util.Queue;
import java.util.Set;
import org.apollo.game.model.Position;
import org.apollo.game.model.area.RegionRepository;
/**
* A {@link PathfindingAlgorithm} that utilises the A* algorithm to find a solution.
@@ -32,10 +33,12 @@ public final class AStarPathfindingAlgorithm extends PathfindingAlgorithm {
/**
* Creates the A* pathfinding algorithm with the specified heuristic.
*
*
* @param repository The {@link RegionRepository}.
* @param heuristic The heuristic.
*/
public AStarPathfindingAlgorithm(Heuristic heuristic) {
public AStarPathfindingAlgorithm(RegionRepository repository, Heuristic heuristic) {
super(repository);
this.heuristic = heuristic;
}
@@ -5,7 +5,6 @@ import java.util.Optional;
import org.apollo.game.model.Direction;
import org.apollo.game.model.Position;
import org.apollo.game.model.World;
import org.apollo.game.model.area.Region;
import org.apollo.game.model.area.RegionRepository;
import org.apollo.game.model.entity.Entity.EntityType;
@@ -20,9 +19,18 @@ import com.google.common.base.Preconditions;
abstract class PathfindingAlgorithm {
/**
* The repository of Regions.
* The RegionRepository.
*/
private static final RegionRepository REPOSITORY = World.getWorld().getRegionRepository();
private final RegionRepository repository;
/**
* Creates the PathfindingAlgorithm.
*
* @param repository The {@link RegionRepository}.
*/
public PathfindingAlgorithm(RegionRepository repository) {
this.repository = repository;
}
/**
* Finds a valid path from the origin {@link Position} to the target one.
@@ -77,7 +85,7 @@ abstract class PathfindingAlgorithm {
}
Position next = new Position(x, y, height);
Region region = REPOSITORY.get(next.getRegionCoordinates());
Region region = repository.get(next.getRegionCoordinates());
if (region.traversable(next, EntityType.NPC, direction) && (positions.length == 0 || inside(next, positions))) {
return true;
}
@@ -6,6 +6,7 @@ import java.util.Optional;
import org.apollo.game.model.Direction;
import org.apollo.game.model.Position;
import org.apollo.game.model.area.RegionRepository;
/**
* A very simple pathfinding algorithm that simply walks in the direction of the target until it either reaches it or is
@@ -15,6 +16,15 @@ import org.apollo.game.model.Position;
*/
public final class SimplePathfindingAlgorithm extends PathfindingAlgorithm {
/**
* Creates the SimplePathfindingAlgorithm.
*
* @param repository The {@link RegionRepository}.
*/
public SimplePathfindingAlgorithm(RegionRepository repository) {
super(repository);
}
/**
* The Optional containing the boundary Positions.
*/
@@ -12,7 +12,6 @@ import org.apollo.game.message.impl.OpenInterfaceMessage;
import org.apollo.game.message.impl.OpenInterfaceSidebarMessage;
import org.apollo.game.message.impl.OpenOverlayMessage;
import org.apollo.game.message.impl.OpenSidebarMessage;
import org.apollo.game.model.World;
import org.apollo.game.model.entity.Player;
import org.apollo.game.model.event.impl.CloseInterfacesEvent;
import org.apollo.game.model.inter.dialogue.DialogueListener;
@@ -87,7 +86,7 @@ public final class InterfaceSet {
*/
public void close() {
CloseInterfacesEvent event = new CloseInterfacesEvent(player);
if (World.getWorld().submit(event)) {
if (player.getWorld().submit(event)) {
closeAndNotify();
player.send(new CloseInterfaceMessage());
}
@@ -7,6 +7,7 @@ import java.util.Queue;
import java.util.Random;
import org.apollo.game.model.Position;
import org.apollo.game.model.area.RegionRepository;
import org.apollo.game.model.entity.Npc;
import org.apollo.game.model.entity.WalkingQueue;
import org.apollo.game.model.entity.path.SimplePathfindingAlgorithm;
@@ -39,7 +40,7 @@ public final class NpcMovementTask extends ScheduledTask {
/**
* The PathfindingAlgorithm used by this Task.
*/
private final SimplePathfindingAlgorithm algorithm = new SimplePathfindingAlgorithm();
private final SimplePathfindingAlgorithm algorithm;
/**
* The Queue of Npcs.
@@ -48,9 +49,12 @@ public final class NpcMovementTask extends ScheduledTask {
/**
* Creates the NpcMovementTask.
*
* @param repository The {@link RegionRepository}.
*/
public NpcMovementTask() {
public NpcMovementTask(RegionRepository repository) {
super(DELAY, false);
algorithm = new SimplePathfindingAlgorithm(repository);
}
/**
@@ -1,5 +1,9 @@
package org.apollo.game.sync;
import org.apollo.game.model.entity.Npc;
import org.apollo.game.model.entity.Player;
import org.apollo.util.MobRepository;
/**
* The {@link ClientSynchronizer} manages the update sequence which keeps clients synchronized with the in-game world.
* There are two implementations distributed with Apollo: {@link SequentialClientSynchronizer} which is optimized for a
@@ -16,7 +20,10 @@ public abstract class ClientSynchronizer {
/**
* Synchronizes the state of the clients with the state of the server.
*
* @param players The {@link MobRepository} containing the {@link Player}s.
* @param npcs The {@link MobRepository} containing the {@link Npc}s.
*/
public abstract void synchronize();
public abstract void synchronize(MobRepository<Player> players, MobRepository<Npc> npcs);
}
@@ -10,7 +10,6 @@ import java.util.concurrent.ThreadFactory;
import org.apollo.game.GameService;
import org.apollo.game.message.impl.RegionUpdateMessage;
import org.apollo.game.model.World;
import org.apollo.game.model.area.RegionCoordinates;
import org.apollo.game.model.entity.Npc;
import org.apollo.game.model.entity.Player;
@@ -58,9 +57,7 @@ public final class ParallelClientSynchronizer extends ClientSynchronizer {
}
@Override
public void synchronize() {
MobRepository<Player> players = World.getWorld().getPlayerRepository();
MobRepository<Npc> npcs = World.getWorld().getNpcRepository();
public void synchronize(MobRepository<Player> players, MobRepository<Npc> npcs) {
int playerCount = players.size();
int npcCount = npcs.size();
@@ -6,7 +6,6 @@ import java.util.Map;
import org.apollo.game.GameService;
import org.apollo.game.message.impl.RegionUpdateMessage;
import org.apollo.game.model.World;
import org.apollo.game.model.area.RegionCoordinates;
import org.apollo.game.model.entity.Npc;
import org.apollo.game.model.entity.Player;
@@ -31,10 +30,7 @@ import org.apollo.util.MobRepository;
public final class SequentialClientSynchronizer extends ClientSynchronizer {
@Override
public void synchronize() {
MobRepository<Player> players = World.getWorld().getPlayerRepository();
MobRepository<Npc> npcs = World.getWorld().getNpcRepository();
public void synchronize(MobRepository<Player> players, MobRepository<Npc> npcs) {
Map<RegionCoordinates, List<RegionUpdateMessage>> updates = new HashMap<>();
Map<RegionCoordinates, List<RegionUpdateMessage>> snapshots = new HashMap<>();
@@ -6,7 +6,6 @@ import java.util.List;
import org.apollo.game.message.impl.NpcSynchronizationMessage;
import org.apollo.game.model.Position;
import org.apollo.game.model.World;
import org.apollo.game.model.entity.Npc;
import org.apollo.game.model.entity.Player;
import org.apollo.game.sync.seg.AddNpcSegment;
@@ -50,7 +49,8 @@ public final class NpcSynchronizationTask extends SynchronizationTask {
for (Iterator<Npc> it = localNpcs.iterator(); it.hasNext();) {
Npc npc = it.next();
if (!npc.isActive() || npc.isTeleporting() || npc.getPosition().getLongestDelta(playerPosition) > player.getViewingDistance()) {
if (!npc.isActive() || npc.isTeleporting()
|| npc.getPosition().getLongestDelta(playerPosition) > player.getViewingDistance()) {
it.remove();
segments.add(new RemoveMobSegment());
} else {
@@ -60,7 +60,7 @@ public final class NpcSynchronizationTask extends SynchronizationTask {
int added = 0;
for (Npc npc : World.getWorld().getNpcRepository()) {
for (Npc npc : player.getWorld().getNpcRepository()) {
if (localNpcs.size() >= 255) {
player.flagExcessiveNpcs();
break;
@@ -69,7 +69,8 @@ public final class NpcSynchronizationTask extends SynchronizationTask {
}
Position npcPosition = npc.getPosition();
if (npcPosition.isWithinDistance(playerPosition, player.getViewingDistance()) && !localNpcs.contains(npc) && npcPosition.getHeight() == playerPosition.getHeight()) {
if (npcPosition.isWithinDistance(playerPosition, player.getViewingDistance()) && !localNpcs.contains(npc)
&& npcPosition.getHeight() == playerPosition.getHeight()) {
localNpcs.add(npc);
added++;
npc.turnTo(npc.getFacingPosition());
@@ -6,7 +6,6 @@ import java.util.List;
import org.apollo.game.message.impl.PlayerSynchronizationMessage;
import org.apollo.game.model.Position;
import org.apollo.game.model.World;
import org.apollo.game.model.entity.Player;
import org.apollo.game.sync.block.AppearanceBlock;
import org.apollo.game.sync.block.ChatBlock;
@@ -80,7 +79,7 @@ public final class PlayerSynchronizationTask extends SynchronizationTask {
int added = 0;
MobRepository<Player> repository = World.getWorld().getPlayerRepository();
MobRepository<Player> repository = player.getWorld().getPlayerRepository();
for (Iterator<Player> it = repository.iterator(); it.hasNext();) {
Player other = it.next();
if (localPlayers.size() >= 255) {
@@ -12,7 +12,6 @@ import org.apollo.game.message.impl.GroupedRegionUpdateMessage;
import org.apollo.game.message.impl.RegionChangeMessage;
import org.apollo.game.message.impl.RegionUpdateMessage;
import org.apollo.game.model.Position;
import org.apollo.game.model.World;
import org.apollo.game.model.area.Region;
import org.apollo.game.model.area.RegionCoordinates;
import org.apollo.game.model.area.RegionRepository;
@@ -169,7 +168,7 @@ public final class PrePlayerSynchronizationTask extends SynchronizationTask {
RegionCoordinates base = position.getRegionCoordinates();
int baseX = base.getX(), baseY = base.getY();
RegionRepository repository = World.getWorld().getRegionRepository();
RegionRepository repository = player.getWorld().getRegionRepository();
List<GroupedRegionUpdateMessage> messages = new ArrayList<>();
for (int x = baseX - REGION_COUNT; x <= baseX + REGION_COUNT; x++) {
@@ -11,6 +11,7 @@ import org.apollo.game.message.Message;
import org.apollo.game.message.handler.MessageHandler;
import org.apollo.game.message.handler.MessageHandlerChain;
import org.apollo.game.message.handler.MessageHandlerChainGroup;
import org.apollo.game.model.World;
import org.apollo.util.xml.XmlNode;
import org.apollo.util.xml.XmlParser;
import org.xml.sax.SAXException;
@@ -45,15 +46,13 @@ public final class MessageHandlerChainParser {
/**
* Parses the XML and produces a group of {@link MessageHandlerChain}s.
*
* @param world The {@link World} this MessageHandlerChainGroup is for.
* @return A {@link MessageHandlerChainGroup}.
* @throws IOException If an I/O error occurs.
* @throws SAXException If a SAX error occurs.
* @throws ClassNotFoundException If a class was not found.
* @throws IllegalAccessException If a class was accessed illegally.
* @throws InstantiationException If a class could not be instantiated.
* @return A {@link MessageHandlerChainGroup}.
* @throws ReflectiveOperationException If a reflection error occurs.
*/
@SuppressWarnings("unchecked")
public MessageHandlerChainGroup parse() throws IOException, SAXException, ClassNotFoundException, InstantiationException, IllegalAccessException {
public MessageHandlerChainGroup parse(World world) throws IOException, SAXException, ReflectiveOperationException {
XmlNode messages = parser.parse(is);
if (!messages.getName().equals("messages")) {
throw new IOException("Root node name is not 'messages'.");
@@ -80,6 +79,7 @@ public final class MessageHandlerChainParser {
throw new IOException("Type node must have a value.");
}
@SuppressWarnings("unchecked")
Class<? extends Message> messageClass = (Class<? extends Message>) Class.forName(messageClassName);
List<MessageHandler<?>> handlers = new ArrayList<>();
@@ -93,13 +93,15 @@ public final class MessageHandlerChainParser {
throw new IOException("Handler node must have a value.");
}
Class<? extends MessageHandler<?>> handlerClass = (Class<? extends MessageHandler<?>>) Class.forName(handlerClassName);
MessageHandler<?> handler = handlerClass.newInstance();
@SuppressWarnings("unchecked")
Class<? extends MessageHandler<?>> handlerClass = (Class<? extends MessageHandler<?>>) Class
.forName(handlerClassName);
MessageHandler<?> handler = handlerClass.getConstructor(World.class).newInstance(world);
handlers.add(handler);
}
MessageHandler<?>[] handlersArray = handlers.toArray(new MessageHandler<?>[handlers.size()]);
@SuppressWarnings("rawtypes")
@SuppressWarnings({ "rawtypes", "unchecked" })
MessageHandlerChain<?> chain = new MessageHandlerChain(handlersArray);
chains.put(messageClass, chain);
@@ -19,6 +19,7 @@ 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.World;
import org.apollo.game.model.entity.Player;
import org.apollo.game.model.entity.Skill;
import org.apollo.game.model.entity.SkillSet;
@@ -48,7 +49,16 @@ import com.lambdaworks.crypto.SCryptUtil;
* @author Graham
* @author Major
*/
public final class BinaryPlayerSerializer implements PlayerSerializer {
public final class BinaryPlayerSerializer extends PlayerSerializer {
/**
* Creates the BinaryPlayerSerializer.
*
* @param world The {@link World} to place the {@link Player}s in.
*/
public BinaryPlayerSerializer(World world) {
super(world);
}
/**
* The Path to the saved games directory.
@@ -69,7 +79,7 @@ public final class BinaryPlayerSerializer implements PlayerSerializer {
public PlayerLoaderResponse loadPlayer(PlayerCredentials credentials) throws IOException {
Path path = getFile(credentials.getUsername());
if (!Files.exists(path)) {
Player player = new Player(credentials, TUTORIAL_ISLAND_SPAWN);
Player player = new Player(world, credentials, TUTORIAL_ISLAND_SPAWN);
credentials.setPassword(SCryptUtil.scrypt(credentials.getPassword(), 16384, 8, 1));
return new PlayerLoaderResponse(LoginConstants.STATUS_OK, player);
@@ -108,7 +118,7 @@ public final class BinaryPlayerSerializer implements PlayerSerializer {
colors[slot] = in.readUnsignedByte();
}
Player player = new Player(credentials, new Position(x, y, height));
Player player = new Player(world, credentials, new Position(x, y, height));
player.setPrivilegeLevel(privilege);
player.setMembers(members);
player.setChatPrivacy(chatPrivacy);
@@ -1,5 +1,6 @@
package org.apollo.io.player;
import org.apollo.game.model.World;
import org.apollo.game.model.entity.Player;
import org.apollo.game.model.entity.setting.MembershipStatus;
import org.apollo.game.model.entity.setting.PrivilegeLevel;
@@ -12,13 +13,22 @@ import org.apollo.security.PlayerCredentials;
* @author Graham
* @author Major
*/
public final class DummyPlayerSerializer implements PlayerSerializer {
public final class DummyPlayerSerializer extends PlayerSerializer {
/**
* Creates the DummyPlayerSerializer.
*
* @param world The {@link World} to place the {@link Player}s in.
*/
public DummyPlayerSerializer(World world) {
super(world);
}
@Override
public PlayerLoaderResponse loadPlayer(PlayerCredentials credentials) {
int status = LoginConstants.STATUS_OK;
Player player = new Player(credentials, TUTORIAL_ISLAND_SPAWN);
Player player = new Player(world, credentials, TUTORIAL_ISLAND_SPAWN);
player.setPrivilegeLevel(PrivilegeLevel.ADMINISTRATOR);
player.setMembers(MembershipStatus.PAID);
@@ -1,5 +1,6 @@
package org.apollo.io.player;
import org.apollo.game.model.World;
import org.apollo.game.model.entity.Player;
import org.apollo.security.PlayerCredentials;
@@ -8,7 +9,16 @@ import org.apollo.security.PlayerCredentials;
*
* @author Major
*/
public final class JdbcPlayerSerializer implements PlayerSerializer {
public final class JdbcPlayerSerializer extends PlayerSerializer {
/**
* Creates the JdbcPlayerSerializer.
*
* @param world The {@link World} to place the {@link Player}s in.
*/
public JdbcPlayerSerializer(World world) {
super(world);
}
@Override
public void savePlayer(Player player) throws Exception {
+19 -4
View File
@@ -1,6 +1,7 @@
package org.apollo.io.player;
import org.apollo.game.model.Position;
import org.apollo.game.model.World;
import org.apollo.game.model.entity.Player;
import org.apollo.security.PlayerCredentials;
@@ -11,12 +12,26 @@ import org.apollo.security.PlayerCredentials;
* @author Graham
* @author Major
*/
public interface PlayerSerializer {
public abstract class PlayerSerializer {
/**
* The spawn point for Players, on Tutorial Island.
*/
Position TUTORIAL_ISLAND_SPAWN = new Position(3093, 3104);
protected static final Position TUTORIAL_ISLAND_SPAWN = new Position(3093, 3104);
/**
* The World this PlayerSerializer is for.
*/
protected final World world;
/**
* Creates the PlayerSerializer.
*
* @param world The {@link World} this PlayerSerializer is for.
*/
public PlayerSerializer(World world) {
this.world = world;
}
/**
* Loads a {@link Player}.
@@ -25,7 +40,7 @@ public interface PlayerSerializer {
* @return The {@link PlayerLoaderResponse}.
* @throws Exception If an error occurs.
*/
public PlayerLoaderResponse loadPlayer(PlayerCredentials credentials) throws Exception;
public abstract PlayerLoaderResponse loadPlayer(PlayerCredentials credentials) throws Exception;
/**
* Saves a {@link Player}.
@@ -33,6 +48,6 @@ public interface PlayerSerializer {
* @param player The Player to save.
* @throws Exception If an error occurs.
*/
public void savePlayer(Player player) throws Exception;
public abstract void savePlayer(Player player) throws Exception;
}
+7 -6
View File
@@ -7,6 +7,7 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.apollo.Service;
import org.apollo.game.model.World;
import org.apollo.game.model.entity.Player;
import org.apollo.io.player.PlayerLoaderResponse;
import org.apollo.io.player.PlayerSerializer;
@@ -41,9 +42,11 @@ public final class LoginService extends Service {
/**
* Creates the login service.
*
* @param world The {@link World} to log Players in to.
* @throws Exception If an error occurs.
*/
public LoginService() throws Exception {
public LoginService(World world) throws Exception {
super(world);
init();
}
@@ -52,11 +55,9 @@ public final class LoginService extends Service {
*
* @throws SAXException If there is an error parsing the XML file.
* @throws IOException If there is an error accessing the file.
* @throws ClassNotFoundException If the player loader/saver implementation could not be found.
* @throws IllegalAccessException If the player loader/saver implementation could not be accessed.
* @throws InstantiationException If the player loader/saver implementation could not be instantiated.
* @throws ReflectiveOperationException If the {@link PlayerSerializer} implementation could not be created.
*/
private void init() throws SAXException, IOException, ClassNotFoundException, InstantiationException, IllegalAccessException {
private void init() throws SAXException, IOException, ReflectiveOperationException {
XmlParser parser = new XmlParser();
XmlNode rootNode;
@@ -74,7 +75,7 @@ public final class LoginService extends Service {
}
Class<?> clazz = Class.forName(serializer.getValue());
this.serializer = (PlayerSerializer) clazz.newInstance();
this.serializer = (PlayerSerializer) clazz.getConstructor(World.class).newInstance(world);
}
/**
@@ -22,7 +22,7 @@ public final class UpdateEncoder extends MessageToMessageEncoder<OnDemandRespons
int chunkId = response.getChunkId();
ByteBuf chunkData = response.getChunkData();
ByteBuf buffer = ctx.alloc().buffer(6 + chunkData.readableBytes());
ByteBuf buffer = ctx.alloc().buffer(2 * Byte.BYTES + 2 * Short.BYTES + chunkData.readableBytes());
buffer.writeByte(descriptor.getType() - 1);
buffer.writeShort(descriptor.getFile());
buffer.writeShort(fileSize);
@@ -10,7 +10,7 @@ import org.apollo.net.release.MessageEncoder;
*
* @author Major
*/
public final class MobAnimationResetEventEncoder extends MessageEncoder<MobAnimationResetMessage> {
public final class MobAnimationResetMessageEncoder extends MessageEncoder<MobAnimationResetMessage> {
@Override
public GamePacket encode(MobAnimationResetMessage message) {
+3 -3
View File
@@ -115,11 +115,11 @@ public final class LoginSession extends Session {
IsaacRandomPair randomPair = request.getRandomPair();
Release release = serverContext.getRelease();
channel.pipeline().addFirst("eventEncoder", new GameMessageEncoder(release));
channel.pipeline().addBefore("eventEncoder", "gameEncoder", new GamePacketEncoder(randomPair.getEncodingRandom()));
channel.pipeline().addFirst("messageEncoder", new GameMessageEncoder(release));
channel.pipeline().addBefore("messageEncoder", "gameEncoder", new GamePacketEncoder(randomPair.getEncodingRandom()));
channel.pipeline().addBefore("handler", "gameDecoder", new GamePacketDecoder(randomPair.getDecodingRandom(), serverContext.getRelease()));
channel.pipeline().addAfter("gameDecoder", "eventDecoder", new GameMessageDecoder(release));
channel.pipeline().addAfter("gameDecoder", "messageDecoder", new GameMessageDecoder(release));
channel.pipeline().remove("loginDecoder");
channel.pipeline().remove("loginEncoder");
@@ -47,14 +47,11 @@ public final class OnDemandRequestWorker extends RequestWorker<OnDemandRequest,
int length = buffer.remaining();
for (int chunk = 0; buffer.remaining() > 0; chunk++) {
int chunkSize = buffer.remaining();
if (chunkSize > CHUNK_LENGTH) {
chunkSize = CHUNK_LENGTH;
}
int chunkSize = Math.min(buffer.remaining(), CHUNK_LENGTH);
byte[] tmp = new byte[chunkSize];
buffer.get(tmp, 0, tmp.length);
ByteBuf chunkData = Unpooled.wrappedBuffer(tmp, 0, chunkSize);
byte[] data = new byte[chunkSize];
buffer.get(data, 0, data.length);
ByteBuf chunkData = Unpooled.wrappedBuffer(data, 0, chunkSize);
OnDemandResponse response = new OnDemandResponse(desc, length, chunk, chunkData);
channel.writeAndFlush(response);
+6 -2
View File
@@ -12,6 +12,7 @@ import java.util.logging.Logger;
import org.apollo.Service;
import org.apollo.fs.IndexedFileSystem;
import org.apollo.game.model.World;
/**
* A class which services file requests.
@@ -51,9 +52,12 @@ public final class UpdateService extends Service {
private final List<RequestWorker<?, ?>> workers = new ArrayList<>();
/**
* Creates the update service.
* Creates the UpdateService.
*
* @param world The {@link World} the update service is for.
*/
public UpdateService() {
public UpdateService(World world) {
super(world);
int totalThreads = REQUEST_TYPES * THREADS_PER_REQUEST_TYPE;
service = Executors.newFixedThreadPool(totalThreads);
}
+3 -36
View File
@@ -2,15 +2,10 @@ package org.apollo.util.plugin;
import org.apollo.ServerContext;
import org.apollo.game.GameService;
import org.apollo.game.command.CommandListener;
import org.apollo.game.message.Message;
import org.apollo.game.message.handler.MessageHandler;
import org.apollo.game.message.handler.MessageHandlerChain;
import org.apollo.game.message.handler.MessageHandlerChainGroup;
import org.apollo.game.model.World;
import org.apollo.game.model.event.EventListener;
import org.apollo.game.model.event.impl.LoginEvent;
import org.apollo.game.model.event.impl.LogoutEvent;
/**
* The {@link PluginContext} contains methods a plugin can use to interface with the server, for example, by adding
@@ -22,42 +17,14 @@ import org.apollo.game.model.event.impl.LogoutEvent;
public final class PluginContext {
/**
* Adds a {@link CommandListener}.
*
* @param name The name of the listener.
* @param listener The listener.
*/
public static void addCommandListener(String name, CommandListener listener) {
World.getWorld().getCommandDispatcher().register(name, listener);
}
/**
* Adds an {@link EventListener} for a {@link LoginEvent}.
*
* @param listener The listener.
*/
public static void addLoginListener(EventListener<LoginEvent> listener) {
World.getWorld().listenFor(LoginEvent.class, listener);
}
/**
* Adds an {@link EventListener} for a {@link LogoutEvent}.
*
* @param listener The listener.
*/
public static void addLogoutListener(EventListener<LogoutEvent> listener) {
World.getWorld().listenFor(LogoutEvent.class, listener);
}
/**
* The server context.
* The ServerContext.
*/
private final ServerContext context;
/**
* Creates the plugin context.
* Creates the PluginContext.
*
* @param context The server context.
* @param context The {@link ServerContext}.
*/
public PluginContext(ServerContext context) {
this.context = context;
+15 -6
View File
@@ -15,6 +15,7 @@ import java.util.TreeSet;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.apollo.game.model.World;
import org.apollo.io.PluginMetaDataParser;
import org.xml.sax.SAXException;
@@ -36,12 +37,19 @@ public final class PluginManager {
private final PluginContext context;
/**
* Creates the plugin manager.
*
* @param context The plugin context.
* The World this PluginManager is for.
*/
public PluginManager(PluginContext context) {
private final World world;
/**
* Creates the PluginManager.
*
* @param world The {@link World} the PluginManager is for.
* @param context The PluginContext.
*/
public PluginManager(World world, PluginContext context) {
this.context = context;
this.world = world;
initAuthors();
}
@@ -138,7 +146,7 @@ public final class PluginManager {
Map<String, PluginMetaData> plugins = createMap(findPlugins());
Set<PluginMetaData> started = new HashSet<>();
PluginEnvironment env = new RubyPluginEnvironment(); // TODO isolate plugins if possible in the future!
PluginEnvironment env = new RubyPluginEnvironment(world); // TODO isolate plugins if possible in the future!
env.setContext(context);
for (PluginMetaData plugin : plugins.values()) {
@@ -156,7 +164,8 @@ public final class PluginManager {
* @throws DependencyException If a dependency error occurs.
* @throws IOException If an I/O error occurs.
*/
private void start(PluginEnvironment env, PluginMetaData plugin, Map<String, PluginMetaData> plugins, Set<PluginMetaData> started) throws DependencyException, IOException {
private void start(PluginEnvironment env, PluginMetaData plugin, Map<String, PluginMetaData> plugins,
Set<PluginMetaData> started) throws DependencyException, IOException {
// TODO check for cyclic dependencies! this way just won't cut it, we need an exception
if (started.contains(plugin)) {
return;
@@ -20,12 +20,19 @@ public final class RubyPluginEnvironment implements PluginEnvironment {
*/
private final ScriptingContainer container = new ScriptingContainer();
/**
* The World this RubyPluginEnvironment is for.
*/
private final World world;
/**
* Creates and bootstraps the Ruby plugin environment.
*
* @param world The {@link World} this RubyPluginEnvironment is for.
* @throws IOException If an I/O error occurs during bootstrapping.
*/
public RubyPluginEnvironment() throws IOException {
public RubyPluginEnvironment(World world) throws IOException {
this.world = world;
parseBootstrapper();
}
@@ -54,7 +61,7 @@ public final class RubyPluginEnvironment implements PluginEnvironment {
@Override
public void setContext(PluginContext context) {
container.put("$ctx", context);
container.put("$world", World.getWorld());
container.put("$world", world);
}
}