mirror of
https://github.com/2006-Scape/apollo.git
synced 2026-07-05 08:40:08 +00:00
Housekeeping
This commit is contained in:
@@ -0,0 +1,239 @@
|
||||
# A script bootstrapper for the rest of the plugins, which wraps Apollo's
|
||||
# verbose Java-style API in a Ruby-style API.
|
||||
|
||||
# ********************************** WARNING **********************************
|
||||
# * If you do not really understand what this is for, do not edit it without *
|
||||
# * creating a backup! Many plugins rely on the behaviour of this script, and *
|
||||
# * will break if you mess it up. *
|
||||
# * *
|
||||
# * This is actually part of the core server and in an ideal world shouldn't *
|
||||
# * be changed. *
|
||||
# *****************************************************************************
|
||||
|
||||
require 'java'
|
||||
|
||||
java_import 'org.apollo.game.command.CommandListener'
|
||||
java_import 'org.apollo.game.message.handler.MessageHandler'
|
||||
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.event.PlayerEvent'
|
||||
java_import 'org.apollo.game.model.event.impl.LoginEvent'
|
||||
java_import 'org.apollo.game.model.event.ProxyEvent'
|
||||
java_import 'org.apollo.game.model.event.ProxyEventListener'
|
||||
java_import 'org.apollo.game.model.entity.setting.PrivilegeLevel'
|
||||
java_import 'org.apollo.game.scheduling.ScheduledTask'
|
||||
java_import 'org.apollo.game.plugin.PluginContext'
|
||||
|
||||
# Alias the privilege levels.
|
||||
RIGHTS_ADMIN = PrivilegeLevel::ADMINISTRATOR
|
||||
RIGHTS_MOD = PrivilegeLevel::MODERATOR
|
||||
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
|
||||
|
||||
# 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 LogoutListener that executes a Proc object with the player argument.
|
||||
class ProcEventListener
|
||||
java_implements EventListener
|
||||
|
||||
# Creates the ProcEventListener.
|
||||
def initialize(block)
|
||||
super()
|
||||
@block = block
|
||||
end
|
||||
|
||||
# Executes the block handling the Event.
|
||||
def handle(event)
|
||||
args = [event]
|
||||
args << event.player if event.is_a?(PlayerEvent)
|
||||
@block.call(*args)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# A MessageHandler which executes a Proc object with two arguments: the player and the message.
|
||||
class ProcMessageHandler < MessageHandler
|
||||
|
||||
# Creates the ProcMessageHandler.
|
||||
def initialize(block, option)
|
||||
super($world)
|
||||
@block = block
|
||||
@option = option
|
||||
end
|
||||
|
||||
# Handles the message.
|
||||
def handle(player, message)
|
||||
@block.call(player, message) if @option == 0 || @option == message.option
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
end
|
||||
|
||||
# Schedules a ScheduledTask. Can be used in two ways: passing an existing
|
||||
# ScheduledTask object or passing a block along with one or two parameters: the
|
||||
# delay (in pulses) and, optionally, the immediate flag.
|
||||
#
|
||||
# If the immediate flag is not given, it defaults to false.
|
||||
#
|
||||
# The ScheduledTask object is passed to the block so that methods such as
|
||||
# setDelay and stop can be called. execute MUST NOT be called - if it is, the
|
||||
# behaviour is undefined (and most likely it'll be bad).
|
||||
def schedule(*args, &block)
|
||||
if block_given?
|
||||
fail 'Invalid combination of arguments.' unless (1..2).include?(args.length)
|
||||
delay = args[0]
|
||||
|
||||
immediate = args.length == 2 ? args[1] : false
|
||||
$world.schedule(ProcScheduledTask.new(delay, immediate, block))
|
||||
elsif args.length == 1
|
||||
$world.schedule(args[0])
|
||||
else
|
||||
fail 'Invalid combination of arguments.'
|
||||
end
|
||||
end
|
||||
|
||||
@@proxy_listener = ProxyEventListener.new
|
||||
$world.listen_for(ProxyEvent.java_class, @@proxy_listener)
|
||||
|
||||
# Defines some sort of action to take upon an message. The following types of message are currently
|
||||
# valid:
|
||||
#
|
||||
# * :command
|
||||
# * :message
|
||||
# * :button
|
||||
# * 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 STANDARD. The block should have two arguments:
|
||||
# player and command.
|
||||
#
|
||||
# An message takes no arguments. The block should have two arguments: the player and the message
|
||||
# object.
|
||||
#
|
||||
# A button takes one argument (the id). The block should have one argument: the player who clicked
|
||||
# the button.
|
||||
def on(type, *args, &block)
|
||||
case type
|
||||
when :command then on_command(args, block)
|
||||
when :message then on_message(args, block)
|
||||
when :button then on_button(args, block)
|
||||
else
|
||||
class_name = type.to_s.camelize.concat('Event')
|
||||
|
||||
begin
|
||||
type = Java::JavaClass.for_name("org.apollo.game.model.event.impl.#{class_name}")
|
||||
rescue
|
||||
@@proxy_listener.add(class_name, ProcEventListener.new(block))
|
||||
return
|
||||
end
|
||||
|
||||
$world.listen_for(type, ProcEventListener.new(block))
|
||||
end
|
||||
end
|
||||
|
||||
# Contains extension methods for World.
|
||||
module WorldExtensions
|
||||
|
||||
# Overrides World#submit, providing special-case behaviour for Events defined in Ruby, which
|
||||
# need to be wrapped in a ProxyEvent, until https://github.com/jruby/jruby/issues/2359 is
|
||||
# resolved.
|
||||
def submit(event)
|
||||
if event.java_class.name.end_with?(".Event", ".PlayerEvent")
|
||||
event = ProxyEvent.new(event.class.name, event)
|
||||
end
|
||||
|
||||
super(event)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# Prepend the methods defined in WorldExtensions to World.
|
||||
class World
|
||||
prepend WorldExtensions
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Defines an action to be taken upon a button press.
|
||||
def on_button(args, proc)
|
||||
fail 'Button must have one argument.' unless args.length == 1
|
||||
|
||||
id = args[0].to_i
|
||||
|
||||
on :message, :button do |player, message|
|
||||
proc.call(player) if message.widget_id == id
|
||||
end
|
||||
end
|
||||
|
||||
# Defines an action to be taken upon a message.
|
||||
# The message can either be a symbol with the lowercase underscored class name, or the class itself.
|
||||
def on_message(args, proc)
|
||||
fail 'Message must have one or two arguments.' unless (1..2).include?(args.length)
|
||||
|
||||
numbers = %w(first second third fourth fifth)
|
||||
message = args[0].to_s
|
||||
option = 0
|
||||
|
||||
(0...numbers.length).each do |index|
|
||||
number = numbers[index]
|
||||
|
||||
if message.start_with?(number)
|
||||
option = index + 1
|
||||
message = message[number.length + 1, message.length]
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
class_name = message.camelize.concat('Message')
|
||||
message = Java::JavaClass.for_name("org.apollo.game.message.impl.#{class_name}")
|
||||
|
||||
$ctx.add_message_handler(message, ProcMessageHandler.new(proc, option))
|
||||
end
|
||||
|
||||
# Defines an action to be taken upon a command.
|
||||
def on_command(args, proc)
|
||||
fail 'Command message must have one or two arguments.' unless (1..2).include?(args.length)
|
||||
|
||||
rights = args.length == 2 ? args[1] : RIGHTS_STANDARD
|
||||
$world.command_dispatcher.register(args[0].to_s, ProcCommandListener.new(rights, proc))
|
||||
end
|
||||
Reference in New Issue
Block a user