mirror of
https://github.com/Rogiel/l2jserver2
synced 2025-12-06 07:32:46 +00:00
Change-Id: Ia7c6094789fa7b0d3cc6c136992b8081efd3c5e5
This commit is contained in:
6
src/main/java/com/l2jserver/GeneralConfiguration.java
Normal file
6
src/main/java/com/l2jserver/GeneralConfiguration.java
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
package com.l2jserver;
|
||||||
|
|
||||||
|
import com.l2jserver.service.configuration.Configuration;
|
||||||
|
|
||||||
|
public interface GeneralConfiguration extends Configuration {
|
||||||
|
}
|
||||||
10
src/main/java/com/l2jserver/L2JConstants.java
Normal file
10
src/main/java/com/l2jserver/L2JConstants.java
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
package com.l2jserver;
|
||||||
|
|
||||||
|
public class L2JConstants {
|
||||||
|
/**
|
||||||
|
* Indicated the supported protocol for this compilation.
|
||||||
|
* <p>
|
||||||
|
* This <b>MUST</b> be hard-coded!
|
||||||
|
*/
|
||||||
|
public static final int SUPPORTED_PROTOCOL = 10;
|
||||||
|
}
|
||||||
@@ -5,6 +5,7 @@ import static org.jboss.netty.channel.Channels.pipeline;
|
|||||||
import org.jboss.netty.channel.ChannelPipeline;
|
import org.jboss.netty.channel.ChannelPipeline;
|
||||||
import org.jboss.netty.channel.ChannelPipelineFactory;
|
import org.jboss.netty.channel.ChannelPipelineFactory;
|
||||||
|
|
||||||
|
import com.google.inject.Injector;
|
||||||
import com.l2jserver.game.net.codec.Lineage2Decoder;
|
import com.l2jserver.game.net.codec.Lineage2Decoder;
|
||||||
import com.l2jserver.game.net.codec.Lineage2Decrypter;
|
import com.l2jserver.game.net.codec.Lineage2Decrypter;
|
||||||
import com.l2jserver.game.net.codec.Lineage2Encoder;
|
import com.l2jserver.game.net.codec.Lineage2Encoder;
|
||||||
@@ -12,8 +13,15 @@ import com.l2jserver.game.net.codec.Lineage2Encrypter;
|
|||||||
import com.l2jserver.game.net.codec.Lineage2PacketReader;
|
import com.l2jserver.game.net.codec.Lineage2PacketReader;
|
||||||
import com.l2jserver.game.net.codec.Lineage2PacketWriter;
|
import com.l2jserver.game.net.codec.Lineage2PacketWriter;
|
||||||
import com.l2jserver.game.net.handler.Lineage2PacketHandler;
|
import com.l2jserver.game.net.handler.Lineage2PacketHandler;
|
||||||
|
import com.l2jserver.service.logging.LoggingService;
|
||||||
|
|
||||||
public class Lineage2PipelineFactory implements ChannelPipelineFactory {
|
public class Lineage2PipelineFactory implements ChannelPipelineFactory {
|
||||||
|
private final Injector injector;
|
||||||
|
|
||||||
|
public Lineage2PipelineFactory(Injector injector) {
|
||||||
|
this.injector = injector;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ChannelPipeline getPipeline() throws Exception {
|
public ChannelPipeline getPipeline() throws Exception {
|
||||||
final ChannelPipeline pipeline = pipeline();
|
final ChannelPipeline pipeline = pipeline();
|
||||||
@@ -27,7 +35,8 @@ public class Lineage2PipelineFactory implements ChannelPipelineFactory {
|
|||||||
pipeline.addLast("header.decoder", new Lineage2Decoder());
|
pipeline.addLast("header.decoder", new Lineage2Decoder());
|
||||||
|
|
||||||
pipeline.addLast("packet.writer", new Lineage2PacketWriter());
|
pipeline.addLast("packet.writer", new Lineage2PacketWriter());
|
||||||
pipeline.addLast("packet.reader", new Lineage2PacketReader());
|
pipeline.addLast("packet.reader", new Lineage2PacketReader(injector,
|
||||||
|
injector.getInstance(LoggingService.class)));
|
||||||
|
|
||||||
pipeline.addLast("packet.handler", new Lineage2PacketHandler());
|
pipeline.addLast("packet.handler", new Lineage2PacketHandler());
|
||||||
|
|
||||||
|
|||||||
@@ -5,32 +5,49 @@ import org.jboss.netty.channel.Channel;
|
|||||||
import org.jboss.netty.channel.ChannelHandlerContext;
|
import org.jboss.netty.channel.ChannelHandlerContext;
|
||||||
import org.jboss.netty.handler.codec.oneone.OneToOneDecoder;
|
import org.jboss.netty.handler.codec.oneone.OneToOneDecoder;
|
||||||
|
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import com.google.inject.Injector;
|
||||||
import com.l2jserver.game.net.packet.ClientPacket;
|
import com.l2jserver.game.net.packet.ClientPacket;
|
||||||
import com.l2jserver.game.net.packet.client.ProtocolVersionPacket;
|
import com.l2jserver.game.net.packet.client.ProtocolVersionPacket;
|
||||||
|
import com.l2jserver.service.logging.Logger;
|
||||||
|
import com.l2jserver.service.logging.LoggingService;
|
||||||
|
|
||||||
public class Lineage2PacketReader extends OneToOneDecoder {
|
public class Lineage2PacketReader extends OneToOneDecoder {
|
||||||
|
private final Injector injector;
|
||||||
|
private final Logger logger;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public Lineage2PacketReader(Injector injector, LoggingService logging) {
|
||||||
|
this.injector = injector;
|
||||||
|
this.logger = logging.getLogger(Lineage2PacketReader.class);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Object decode(ChannelHandlerContext ctx, Channel channel,
|
protected Object decode(ChannelHandlerContext ctx, Channel channel,
|
||||||
Object msg) throws Exception {
|
Object msg) throws Exception {
|
||||||
if (!(msg instanceof ChannelBuffer))
|
if (!(msg instanceof ChannelBuffer))
|
||||||
return msg;
|
return msg;
|
||||||
final ChannelBuffer buffer = (ChannelBuffer) msg;
|
final ChannelBuffer buffer = (ChannelBuffer) msg;
|
||||||
final ClientPacket packet = getPacket(buffer);
|
final ClientPacket packet = createPacket(getPacketClass(buffer));
|
||||||
if (packet == null)
|
if (packet == null)
|
||||||
return null;
|
return null;
|
||||||
packet.read(buffer);
|
packet.read(buffer);
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ClientPacket getPacket(ChannelBuffer buffer) {
|
private ClientPacket createPacket(Class<? extends ClientPacket> type) {
|
||||||
|
return injector.getInstance(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Class<? extends ClientPacket> getPacketClass(ChannelBuffer buffer) {
|
||||||
final short opcode = buffer.readUnsignedByte();
|
final short opcode = buffer.readUnsignedByte();
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
case ProtocolVersionPacket.OPCODE:
|
case ProtocolVersionPacket.OPCODE:
|
||||||
return new ProtocolVersionPacket();
|
return ProtocolVersionPacket.class;
|
||||||
case 0x2b:
|
case 0x2b:
|
||||||
return null;
|
return null;
|
||||||
default:
|
default:
|
||||||
System.out.println("Unk: " + opcode);
|
logger.info("Unknown opcode: " + opcode);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -1,12 +1,23 @@
|
|||||||
package com.l2jserver.game.net.handler;
|
package com.l2jserver.game.net.handler;
|
||||||
|
|
||||||
import org.jboss.netty.channel.ChannelHandlerContext;
|
import org.jboss.netty.channel.ChannelHandlerContext;
|
||||||
|
import org.jboss.netty.channel.ChannelStateEvent;
|
||||||
import org.jboss.netty.channel.MessageEvent;
|
import org.jboss.netty.channel.MessageEvent;
|
||||||
import org.jboss.netty.channel.SimpleChannelHandler;
|
import org.jboss.netty.channel.SimpleChannelHandler;
|
||||||
|
|
||||||
|
import com.l2jserver.game.net.Lineage2Connection;
|
||||||
import com.l2jserver.game.net.packet.ClientPacket;
|
import com.l2jserver.game.net.packet.ClientPacket;
|
||||||
|
|
||||||
public class Lineage2PacketHandler extends SimpleChannelHandler {
|
public class Lineage2PacketHandler extends SimpleChannelHandler {
|
||||||
|
private Lineage2Connection connection;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e)
|
||||||
|
throws Exception {
|
||||||
|
connection = new Lineage2Connection(e.getChannel());
|
||||||
|
super.channelOpen(ctx, e);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
|
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
@@ -14,7 +25,7 @@ public class Lineage2PacketHandler extends SimpleChannelHandler {
|
|||||||
if (!(msg instanceof ClientPacket))
|
if (!(msg instanceof ClientPacket))
|
||||||
return;
|
return;
|
||||||
final ClientPacket packet = (ClientPacket) msg;
|
final ClientPacket packet = (ClientPacket) msg;
|
||||||
packet.process(null);
|
packet.process(connection, null);
|
||||||
super.messageReceived(ctx, e);
|
super.messageReceived(ctx, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
package com.l2jserver.game.net.packet;
|
package com.l2jserver.game.net.packet;
|
||||||
|
|
||||||
|
|
||||||
public abstract class AbstractClientPacket implements ClientPacket {
|
public abstract class AbstractClientPacket implements ClientPacket {
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.l2jserver.game.net.packet;
|
|||||||
import org.jboss.netty.buffer.ChannelBuffer;
|
import org.jboss.netty.buffer.ChannelBuffer;
|
||||||
|
|
||||||
import com.google.inject.Injector;
|
import com.google.inject.Injector;
|
||||||
|
import com.l2jserver.game.net.Lineage2Connection;
|
||||||
|
|
||||||
public interface ClientPacket extends Packet {
|
public interface ClientPacket extends Packet {
|
||||||
/**
|
/**
|
||||||
@@ -19,5 +20,5 @@ public interface ClientPacket extends Packet {
|
|||||||
* @param injector
|
* @param injector
|
||||||
* the injector
|
* the injector
|
||||||
*/
|
*/
|
||||||
void process(Injector injector);
|
void process(Lineage2Connection conn, Injector injector);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package com.l2jserver.game.net.packet;
|
||||||
|
|
||||||
|
import com.google.inject.AbstractModule;
|
||||||
|
import com.l2jserver.game.net.packet.client.ProtocolVersionPacket;
|
||||||
|
|
||||||
|
public class ClientPacketModule extends AbstractModule {
|
||||||
|
@Override
|
||||||
|
protected void configure() {
|
||||||
|
bind(ProtocolVersionPacket.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,13 +2,27 @@ package com.l2jserver.game.net.packet.client;
|
|||||||
|
|
||||||
import org.jboss.netty.buffer.ChannelBuffer;
|
import org.jboss.netty.buffer.ChannelBuffer;
|
||||||
|
|
||||||
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.Injector;
|
import com.google.inject.Injector;
|
||||||
|
import com.l2jserver.L2JConstants;
|
||||||
|
import com.l2jserver.game.net.Lineage2Connection;
|
||||||
import com.l2jserver.game.net.packet.AbstractClientPacket;
|
import com.l2jserver.game.net.packet.AbstractClientPacket;
|
||||||
|
import com.l2jserver.service.logging.Logger;
|
||||||
|
import com.l2jserver.service.logging.LoggingService;
|
||||||
|
|
||||||
public class ProtocolVersionPacket extends AbstractClientPacket {
|
public class ProtocolVersionPacket extends AbstractClientPacket {
|
||||||
public static final int OPCODE = 0x0e;
|
public static final int OPCODE = 0x0e;
|
||||||
|
|
||||||
|
// services
|
||||||
|
private final Logger logger;
|
||||||
|
|
||||||
|
// packet
|
||||||
private int version;
|
private int version;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
protected ProtocolVersionPacket(LoggingService logging) {
|
||||||
|
logger = logging.getLogger(ProtocolVersionPacket.class);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void read(ChannelBuffer buffer) {
|
public void read(ChannelBuffer buffer) {
|
||||||
@@ -16,8 +30,12 @@ public class ProtocolVersionPacket extends AbstractClientPacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void process(Injector injector) {
|
public void process(Lineage2Connection conn, Injector injector) {
|
||||||
|
if(L2JConstants.SUPPORTED_PROTOCOL != version) {
|
||||||
|
logger.info("Incorrect protocol version: "+version);
|
||||||
|
conn.close();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getVersion() {
|
public int getVersion() {
|
||||||
|
|||||||
@@ -8,6 +8,6 @@ import com.l2jserver.model.world.AbstractObject;
|
|||||||
*
|
*
|
||||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
*/
|
*/
|
||||||
public interface Attackable extends WorldCapability {
|
public interface Attackable extends ObjectCapability {
|
||||||
void receiveAttack(Attacker attacker);
|
void receiveAttack(Attacker attacker);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,6 @@ import com.l2jserver.model.world.AbstractObject;
|
|||||||
*
|
*
|
||||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
*/
|
*/
|
||||||
public interface Attacker extends WorldCapability {
|
public interface Attacker extends ObjectCapability {
|
||||||
void attack(Attackable target);
|
void attack(Attackable target);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,6 @@ import com.l2jserver.model.world.AbstractObject;
|
|||||||
*
|
*
|
||||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
*/
|
*/
|
||||||
public interface Castable extends WorldCapability {
|
public interface Castable extends ObjectCapability {
|
||||||
void cast();
|
void cast();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,6 @@ import com.l2jserver.model.world.AbstractObject;
|
|||||||
*
|
*
|
||||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
*/
|
*/
|
||||||
public interface Caster extends WorldCapability {
|
public interface Caster extends ObjectCapability {
|
||||||
void cast(SkillTemplate skill, Castable cast);
|
void cast(SkillTemplate skill, Castable cast);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,6 @@ import com.l2jserver.model.world.AbstractObject;
|
|||||||
*
|
*
|
||||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
*/
|
*/
|
||||||
public interface Child<P extends Parent> extends WorldCapability {
|
public interface Child<P extends Parent> extends ObjectCapability {
|
||||||
public P getParent();
|
public P getParent();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package com.l2jserver.model.world.capability;
|
||||||
|
|
||||||
|
import com.l2jserver.model.template.ItemTemplate;
|
||||||
|
import com.l2jserver.model.world.AbstractObject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines an {@link AbstractObject} that can be consumed.
|
||||||
|
*
|
||||||
|
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
|
*/
|
||||||
|
public interface Consumable extends ObjectCapability {
|
||||||
|
void consume(ItemTemplate item, Castable target);
|
||||||
|
}
|
||||||
@@ -7,6 +7,6 @@ import com.l2jserver.model.world.AbstractObject;
|
|||||||
*
|
*
|
||||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
*/
|
*/
|
||||||
public interface Conversable extends WorldCapability {
|
public interface Conversable extends ObjectCapability {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,6 @@ import com.l2jserver.model.world.AbstractObject;
|
|||||||
*
|
*
|
||||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
*/
|
*/
|
||||||
public interface Dropable extends WorldCapability {
|
public interface Dropable extends ObjectCapability {
|
||||||
void drop();
|
void drop();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import com.l2jserver.model.world.AbstractObject;
|
|||||||
*
|
*
|
||||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
*/
|
*/
|
||||||
public interface Enchantable extends WorldCapability {
|
public interface Enchantable extends ObjectCapability {
|
||||||
public int getEnchantLevel();
|
public int getEnchantLevel();
|
||||||
|
|
||||||
public int setEnchantLevel();
|
public int setEnchantLevel();
|
||||||
|
|||||||
@@ -8,6 +8,6 @@ import com.l2jserver.model.world.AbstractObject;
|
|||||||
*
|
*
|
||||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
*/
|
*/
|
||||||
public interface Equipable extends WorldCapability {
|
public interface Equipable extends ObjectCapability {
|
||||||
void equip(Equiper equiper);
|
void equip(Equiper equiper);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import com.l2jserver.model.world.AbstractObject;
|
|||||||
*
|
*
|
||||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
*/
|
*/
|
||||||
public interface Equiper extends WorldCapability {
|
public interface Equiper extends ObjectCapability {
|
||||||
void equip(Equipable equipable);
|
void equip(Equipable equipable);
|
||||||
|
|
||||||
void setEquipment(Object slot, Equipable equipment);
|
void setEquipment(Object slot, Equipable equipment);
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import com.l2jserver.model.world.event.WorldListener;
|
|||||||
* the event type
|
* the event type
|
||||||
*/
|
*/
|
||||||
public interface Listenable<L extends WorldListener<E>, E extends WorldEvent>
|
public interface Listenable<L extends WorldListener<E>, E extends WorldEvent>
|
||||||
extends WorldCapability {
|
extends ObjectCapability {
|
||||||
/**
|
/**
|
||||||
* Adds a new listener
|
* Adds a new listener
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -9,5 +9,5 @@ import com.l2jserver.model.world.WorldObject;
|
|||||||
*
|
*
|
||||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
*/
|
*/
|
||||||
public interface WorldCapability extends WorldObject {
|
public interface ObjectCapability extends WorldObject {
|
||||||
}
|
}
|
||||||
@@ -8,5 +8,5 @@ import com.l2jserver.model.world.AbstractObject;
|
|||||||
*
|
*
|
||||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
*/
|
*/
|
||||||
public interface Parent extends WorldCapability {
|
public interface Parent extends ObjectCapability {
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,6 @@ import com.l2jserver.model.world.AbstractObject;
|
|||||||
*
|
*
|
||||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
*/
|
*/
|
||||||
public interface Playable extends WorldCapability {
|
public interface Playable extends ObjectCapability {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,6 @@ import com.l2jserver.util.Coordinate;
|
|||||||
*
|
*
|
||||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
*/
|
*/
|
||||||
public interface Positionable extends WorldCapability {
|
public interface Positionable extends ObjectCapability {
|
||||||
Coordinate getPosition();
|
Coordinate getPosition();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import com.l2jserver.service.game.script.Script;
|
|||||||
*
|
*
|
||||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
*/
|
*/
|
||||||
public interface Scriptable extends WorldCapability {
|
public interface Scriptable extends ObjectCapability {
|
||||||
/**
|
/**
|
||||||
* The the current script attached to this object
|
* The the current script attached to this object
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import com.l2jserver.util.Coordinate;
|
|||||||
*
|
*
|
||||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
*/
|
*/
|
||||||
public interface Spawnable extends WorldCapability, Positionable {
|
public interface Spawnable extends ObjectCapability, Positionable {
|
||||||
void spawn(Coordinate coordinate);
|
void spawn(Coordinate coordinate);
|
||||||
|
|
||||||
boolean isSpawned();
|
boolean isSpawned();
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import com.l2jserver.util.Coordinate;
|
|||||||
*
|
*
|
||||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
*/
|
*/
|
||||||
public interface Summunable extends Spawnable {
|
public interface Summonable extends Spawnable {
|
||||||
void summon(Coordinate coordinate);
|
void summon(Coordinate coordinate);
|
||||||
|
|
||||||
boolean isSummoned();
|
boolean isSummoned();
|
||||||
Reference in New Issue
Block a user