Move login and logout listening to the new Event system and update plugins to reflect this move, remove previous listening system, fix minor bug in EventListenerChainSet.

This commit is contained in:
Major-
2015-02-27 04:11:08 +00:00
parent 3e4ecb5c73
commit 06b6f5fb74
23 changed files with 174 additions and 220 deletions
+26 -31
View File
@@ -16,10 +16,9 @@ require 'java'
java_import 'org.apollo.game.command.CommandListener'
java_import 'org.apollo.game.message.handler.MessageHandler'
java_import 'org.apollo.game.login.LoginListener'
java_import 'org.apollo.game.login.LogoutListener'
java_import 'org.apollo.game.model.World'
java_import 'org.apollo.game.model.entity.Player'
java_import 'org.apollo.game.model.event.EventListener'
java_import 'org.apollo.game.model.setting.PrivilegeLevel'
java_import 'org.apollo.game.scheduling.ScheduledTask'
java_import 'org.apollo.util.plugin.PluginContext'
@@ -32,50 +31,43 @@ RIGHTS_STANDARD = PrivilegeLevel::STANDARD
# Extends the (Ruby) String class with a method to convert a lower case,
# underscore delimited string to camel-case.
class String
def camelize
# Converts a ruby snake_case string to camel-case.
def camelize()
gsub(/(?:^|_)(.)/) { $1.upcase }
end
end
# A CommandListener that executes a Proc object with two arguments: the player and the command.
class ProcCommandListener < CommandListener
# Creates the ProcCommandListener.
def initialize(rights, block)
super(rights)
@block = block
end
# Executes the block listening for the command.
def execute(player, command)
@block.call(player, command)
end
end
# A LoginListener that executes a Proc object with the player argument.
class ProcLoginListener
java_implements LoginListener
def initialize(block)
super()
@block = block
end
def execute(player)
@block.call(player)
end
end
# A LogoutListener that executes a Proc object with the player argument.
class ProcLogoutListener
java_implements LogoutListener
class ProcEventListener
java_implements EventListener
# Creates the ProcEventListener.
def initialize(block)
super()
@block = block
end
def execute(player)
@block.call(player)
# Executes the block handling the Event.
def handle(event, context)
@block.call(event, context)
end
end
@@ -84,12 +76,14 @@ end
# context, the player and the message.
class ProcMessageHandler < MessageHandler
# Creates the ProcMessageListener.
def initialize(block, option)
super() # required (with brackets!), see http://jira.codehaus.org/browse/JRUBY-679
super()
@block = block
@option = option
end
# Handles the message.
def handle(ctx, player, message)
@block.call(ctx, player, message) if (@option == 0 || @option == message.option)
end
@@ -99,11 +93,13 @@ end
# A ScheduledTask which executes a Proc object with one argument (itself).
class ProcScheduledTask < ScheduledTask
# Creates the ProcScheduledTask.
def initialize(delay, immediate, block)
super(delay, immediate)
@block = block
end
# Executes the block.
def execute
@block.call(self)
end
@@ -138,8 +134,7 @@ end
# * :command
# * :message
# * :button
# * :login
# * :logout
# * Any valid Event, as a symbol in ruby snake_case form.
#
# A command takes one or two arguments (the command name and optionally the
# minimum rights level to use it). The minimum rights level defaults to
@@ -155,9 +150,10 @@ def on(type, *args, &block)
when :command then on_command(args, block)
when :message then on_message(args, block)
when :button then on_button(args, block)
when :login then on_login(block)
when :logout then on_logout(block)
else raise 'Unknown message type.'
else
class_name = type.to_s.camelize.concat('Event')
type = Java::JavaClass.for_name("org.apollo.game.model.event.impl.#{class_name}")
$world.listen_for(type, ProcEventListener.new(block))
end
end
@@ -189,10 +185,9 @@ def on_message(args, proc)
end
end
if message.is_a?(Symbol)
class_name = message.to_s.camelize.concat('Message')
message = Java::JavaClass.for_name("org.apollo.game.message.impl.#{class_name}")
end
class_name = message.to_s.camelize.concat('Message')
message = Java::JavaClass.for_name("org.apollo.game.message.impl.#{class_name}")
$ctx.add_last_message_handler(message, ProcMessageHandler.new(proc, option))
end
@@ -42,7 +42,8 @@ on :message, :remove_friend do |ctx, player, message|
end
# Update the friend server status and send the friend/ignore lists of the player logging in.
on :login do |player|
on :login do |event, context|
player = event.player
player.send(FriendServerStatusMessage.new(ServerStatus::CONNECTING))
player.send(IgnoreListMessage.new(player.ignored_usernames)) if player.ignored_usernames.size > 0
@@ -62,8 +63,8 @@ on :login do |player|
end
# Notifies the player's friends that the player has logged out.
on :logout do |player|
update_friends(player, 0)
on :logout do |event, context|
update_friends(event.player, 0)
end
+7 -9
View File
@@ -51,15 +51,13 @@ def append_tiara(hash)
end
# Sets the correct config upon login, if the player is wearing a tiara.
on :login do |player|
on :login do |event, context|
player = event.player
hat = player.equipment.get(EquipmentConstants::HAT)
next if hat.nil?
tiara = TIARAS_BY_ID[hat]
unless tiara.nil?
tiara.send_config
else
send_empty_config(player)
unless hat.nil?
tiara = TIARAS_BY_ID[hat]
if tiara.nil? then send_empty_config(player) else tiara.send_config end
end
end
@@ -67,7 +65,7 @@ end
on :message, :second_object_action do |ctx, player, message|
object_id = message.id
tiara = TIARAS_BY_ALTAR[object_id]
return if tiara.nil?
next if tiara.nil?
hat = player.equipment.get(EquipmentConstants::HAT)
@@ -1,38 +0,0 @@
package org.apollo.game.login;
import java.util.ArrayList;
import java.util.List;
import org.apollo.game.model.entity.Player;
/**
* A class that dispatches {@link Player}s to {@link LoginListener}s.
*
* @author Major
*/
public final class LoginDispatcher {
/**
* A {@link List} of login listeners.
*/
private final List<LoginListener> listeners = new ArrayList<>();
/**
* Dispatches a player to the appropriate login listener.
*
* @param player The player.
*/
public void dispatch(Player player) {
listeners.forEach(listener -> listener.execute(player));
}
/**
* Registers a listener with this dispatcher.
*
* @param listener The listener.
*/
public void register(LoginListener listener) {
listeners.add(listener);
}
}
@@ -1,20 +0,0 @@
package org.apollo.game.login;
import org.apollo.game.model.entity.Player;
/**
* A class that should be extended for actions that should be executed when the player logs in.
*
* @author Major
*/
@FunctionalInterface
public interface LoginListener {
/**
* Executes the action for this listener.
*
* @param player The player.
*/
public void execute(Player player);
}
@@ -1,38 +0,0 @@
package org.apollo.game.login;
import java.util.ArrayList;
import java.util.List;
import org.apollo.game.model.entity.Player;
/**
* A class that dispatches {@link Player}s to {@link LogoutListener}s.
*
* @author Major
*/
public final class LogoutDispatcher {
/**
* A {@link List} of logout listeners.
*/
private final List<LogoutListener> listeners = new ArrayList<>();
/**
* Dispatches a player to the appropriate logout listener.
*
* @param player The player.
*/
public void dispatch(Player player) {
listeners.forEach(listener -> listener.execute(player));
}
/**
* Registers a listener with this dispatcher.
*
* @param listener The listener.
*/
public void register(LogoutListener listener) {
listeners.add(listener);
}
}
@@ -1,20 +0,0 @@
package org.apollo.game.login;
import org.apollo.game.model.entity.Player;
/**
* An interface that should be implemented for actions that should be executed when the player logs out.
*
* @author Major
*/
@FunctionalInterface
public interface LogoutListener {
/**
* Executes the action for this listener.
*
* @param player The player.
*/
public void execute(Player player);
}
@@ -1,4 +0,0 @@
/**
* Contains login and logout listeners.
*/
package org.apollo.game.login;
+3 -35
View File
@@ -15,8 +15,6 @@ import org.apollo.fs.decoder.ItemDefinitionDecoder;
import org.apollo.fs.decoder.NpcDefinitionDecoder;
import org.apollo.fs.decoder.ObjectDefinitionDecoder;
import org.apollo.game.command.CommandDispatcher;
import org.apollo.game.login.LoginDispatcher;
import org.apollo.game.login.LogoutDispatcher;
import org.apollo.game.model.area.Sector;
import org.apollo.game.model.area.SectorRepository;
import org.apollo.game.model.def.EquipmentDefinition;
@@ -27,9 +25,9 @@ import org.apollo.game.model.entity.Entity;
import org.apollo.game.model.entity.GameObject;
import org.apollo.game.model.entity.Npc;
import org.apollo.game.model.entity.Player;
import org.apollo.game.model.entity.event.Event;
import org.apollo.game.model.entity.event.EventListener;
import org.apollo.game.model.entity.event.EventListenerChainSet;
import org.apollo.game.model.event.Event;
import org.apollo.game.model.event.EventListener;
import org.apollo.game.model.event.EventListenerChainSet;
import org.apollo.game.scheduling.ScheduledTask;
import org.apollo.game.scheduling.Scheduler;
import org.apollo.io.EquipmentDefinitionParser;
@@ -99,16 +97,6 @@ public final class World {
*/
private final EventListenerChainSet events = new EventListenerChainSet();
/**
* The login dispatcher.
*/
private final LoginDispatcher loginDispatcher = new LoginDispatcher();
/**
* The logout dispatcher.
*/
private final LogoutDispatcher logoutDispatcher = new LogoutDispatcher();
/**
* The {@link MobRepository} of {@link Npc}s.
*/
@@ -160,24 +148,6 @@ public final class World {
return commandDispatcher;
}
/**
* Gets the {@link LoginDispatcher}.
*
* @return The dispatcher.
*/
public LoginDispatcher getLoginDispatcher() {
return loginDispatcher;
}
/**
* Gets the {@link LogoutDispatcher}.
*
* @return The dispatcher.
*/
public LogoutDispatcher getLogoutDispatcher() {
return logoutDispatcher;
}
/**
* Gets the npc repository.
*
@@ -394,8 +364,6 @@ public final class World {
Sector sector = sectors.fromPosition(player.getPosition());
sector.removeEntity(player);
logoutDispatcher.dispatch(player);
} else {
logger.warning("Could not find player " + player + " to unregister!");
}
+2 -1
View File
@@ -19,6 +19,7 @@ import org.apollo.game.model.Appearance;
import org.apollo.game.model.Position;
import org.apollo.game.model.World;
import org.apollo.game.model.area.Sector;
import org.apollo.game.model.event.impl.LoginEvent;
import org.apollo.game.model.inter.InterfaceConstants;
import org.apollo.game.model.inter.InterfaceListener;
import org.apollo.game.model.inter.InterfaceSet;
@@ -701,7 +702,7 @@ public final class Player extends Mob {
bank.forceRefresh();
skillSet.forceRefresh();
World.getWorld().getLoginDispatcher().dispatch(this);
World.getWorld().submit(new LoginEvent(this));
}
/**
@@ -1,4 +1,4 @@
package org.apollo.game.model.entity.event;
package org.apollo.game.model.event;
/**
* A type of event that may occur in the game world.
@@ -1,4 +1,4 @@
package org.apollo.game.model.entity.event;
package org.apollo.game.model.event;
/**
* The context of an {@link Event}.
@@ -15,7 +15,7 @@ final class EventContext {
/**
* Terminates the Event chain.
*/
public void terminate() {
public void terminateEvent() {
terminated = true;
}
@@ -1,4 +1,4 @@
package org.apollo.game.model.entity.event;
package org.apollo.game.model.event;
/**
* A listener for an {@link Event} that may occur in the game world.
@@ -1,4 +1,4 @@
package org.apollo.game.model.entity.event;
package org.apollo.game.model.event;
import java.util.ArrayList;
import java.util.List;
@@ -1,4 +1,4 @@
package org.apollo.game.model.entity.event;
package org.apollo.game.model.event;
import java.util.HashMap;
import java.util.Map;
@@ -23,8 +23,8 @@ public final class EventListenerChainSet {
*/
public <E extends Event> boolean notify(E event) {
@SuppressWarnings("unchecked")
EventListenerChain<E> chain = (EventListenerChain<E>) chains.get(event);
return chain.notify(event);
EventListenerChain<E> chain = (EventListenerChain<E>) chains.get(event.getClass());
return (chain == null) ? true : chain.notify(event);
}
/**
@@ -0,0 +1,35 @@
package org.apollo.game.model.event;
import org.apollo.game.model.entity.Player;
/**
* An {@link Event} involving a {@link Player}.
*
* @author Major
*/
public abstract class PlayerEvent extends Event {
/**
* The Player.
*/
private final Player player;
/**
* Creates the PlayerEvent.
*
* @param player The {@link Player}.
*/
public PlayerEvent(Player player) {
this.player = player;
}
/**
* Gets the {@link Player}.
*
* @return The Player.
*/
public Player getPlayer() {
return player;
}
}
@@ -0,0 +1,23 @@
package org.apollo.game.model.event.impl;
import org.apollo.game.model.entity.Player;
import org.apollo.game.model.event.Event;
import org.apollo.game.model.event.PlayerEvent;
/**
* An {@link Event} indicating that a player's open interfaces are about to be closed.
*
* @author Major
*/
public final class CloseInterfacesEvent extends PlayerEvent {
/**
* Creates the CloseInterfacesEvent.
*
* @param player The {@link Player} whose interfaces are being closed.
*/
public CloseInterfacesEvent(Player player) {
super(player);
}
}
@@ -0,0 +1,22 @@
package org.apollo.game.model.event.impl;
import org.apollo.game.model.entity.Player;
import org.apollo.game.model.event.PlayerEvent;
/**
* A {@link PlayerEvent} that is fired when a {@link Player} logs in.
*
* @author Major
*/
public final class LoginEvent extends PlayerEvent {
/**
* Creates the LoginEvent.
*
* @param player The {@link Player} logging in.
*/
public LoginEvent(Player player) {
super(player);
}
}
@@ -0,0 +1,22 @@
package org.apollo.game.model.event.impl;
import org.apollo.game.model.entity.Player;
import org.apollo.game.model.event.PlayerEvent;
/**
* A {@link PlayerEvent} that is fired when a {@link Player} logs out.
*
* @author Major
*/
public final class LogoutEvent extends PlayerEvent {
/**
* Creates the LogoutEvent.
*
* @param player The {@link Player} logging out.
*/
public LogoutEvent(Player player) {
super(player);
}
}
@@ -0,0 +1,4 @@
/**
* Contains Event implementations.
*/
package org.apollo.game.model.event.impl;
@@ -1,4 +1,4 @@
/**
* Contains event-related classes.
*/
package org.apollo.game.model.entity.event;
package org.apollo.game.model.event;
@@ -11,7 +11,9 @@ 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;
import org.apollo.game.model.inv.InventoryListener;
@@ -86,8 +88,11 @@ public final class InterfaceSet {
* Closes the current open interface(s).
*/
public void close() {
closeAndNotify();
player.send(new CloseInterfaceMessage());
CloseInterfacesEvent event = new CloseInterfacesEvent(player);
if (World.getWorld().submit(event)) {
closeAndNotify();
player.send(new CloseInterfaceMessage());
}
}
/**
+10 -10
View File
@@ -3,24 +3,24 @@ package org.apollo.util.plugin;
import org.apollo.ServerContext;
import org.apollo.game.GameService;
import org.apollo.game.command.CommandListener;
import org.apollo.game.login.LoginListener;
import org.apollo.game.login.LogoutListener;
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
* {@link MessageHandler}s to {@link MessageHandlerChain}s.
*
* @author Graham
* @author Major
*/
public final class PluginContext {
// TODO move listeners to world?
/**
* Adds a {@link CommandListener}.
*
@@ -32,21 +32,21 @@ public final class PluginContext {
}
/**
* Adds a {@link LoginListener}.
* Adds an {@link EventListener} for a {@link LoginEvent}.
*
* @param listener The listener.
*/
public static void addLoginListener(LoginListener listener) {
World.getWorld().getLoginDispatcher().register(listener);
public static void addLoginListener(EventListener<LoginEvent> listener) {
World.getWorld().listenFor(LoginEvent.class, listener);
}
/**
* Adds a {@link LogoutListener}.
* Adds an {@link EventListener} for a {@link LogoutEvent}.
*
* @param listener The listener.
*/
public static void addLogoutListener(LogoutListener listener) {
World.getWorld().getLogoutDispatcher().register(listener);
public static void addLogoutListener(EventListener<LogoutEvent> listener) {
World.getWorld().listenFor(LogoutEvent.class, listener);
}
/**