mirror of
https://github.com/Rogiel/l2jserver2
synced 2025-12-08 08:23:11 +00:00
Change-Id: I0cca627373c68d94025647f802a7fa6b419e0aad
This commit is contained in:
@@ -6,14 +6,44 @@ import org.jboss.netty.channel.ChannelFuture;
|
||||
import com.l2jserver.game.net.codec.Lineage2Decrypter;
|
||||
import com.l2jserver.game.net.codec.Lineage2Encrypter;
|
||||
import com.l2jserver.game.net.packet.ServerPacket;
|
||||
import com.l2jserver.model.world.L2Character;
|
||||
|
||||
/**
|
||||
* This object connects the model (structure objects normally stored in the
|
||||
* database) to the controller (protocol stuff).
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class Lineage2Connection {
|
||||
private final Channel channel;
|
||||
private L2Character character;
|
||||
|
||||
public Lineage2Connection(Channel channel) {
|
||||
this.channel = channel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the character
|
||||
*/
|
||||
public boolean hasCharacter() {
|
||||
return character != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the character
|
||||
*/
|
||||
public L2Character getCharacter() {
|
||||
return character;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param character
|
||||
* the character to set
|
||||
*/
|
||||
public void setCharacter(L2Character character) {
|
||||
this.character = character;
|
||||
}
|
||||
|
||||
public Channel getChannel() {
|
||||
return channel;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.l2jserver.game.net.packet.server;
|
||||
import org.jboss.netty.buffer.ChannelBuffer;
|
||||
|
||||
import com.l2jserver.game.net.packet.AbstractServerPacket;
|
||||
import com.l2jserver.model.world.L2Character;
|
||||
|
||||
public class CharSelectionInfoPacket extends AbstractServerPacket {
|
||||
public static final int OPCODE = 0x09;
|
||||
@@ -10,10 +11,10 @@ public class CharSelectionInfoPacket extends AbstractServerPacket {
|
||||
private final String loginName;
|
||||
private final int sessionId;
|
||||
private final int activeId;
|
||||
private final Character[] characters;
|
||||
private final L2Character[] characters;
|
||||
|
||||
public CharSelectionInfoPacket(int opcode, String loginName, int sessionId,
|
||||
int activeId, Character... characters) {
|
||||
int activeId, L2Character... characters) {
|
||||
super(opcode);
|
||||
this.loginName = loginName;
|
||||
this.sessionId = sessionId;
|
||||
|
||||
@@ -1,5 +1,24 @@
|
||||
package com.l2jserver.model.id;
|
||||
|
||||
public interface CharacterID extends ObjectID {
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
import com.l2jserver.db.dao.CharacterDAO;
|
||||
import com.l2jserver.model.world.L2Character;
|
||||
|
||||
public final class CharacterID extends ObjectID<L2Character> {
|
||||
/**
|
||||
* Data Access Object (DAO) for characters
|
||||
*/
|
||||
private final CharacterDAO characterDao;
|
||||
|
||||
@Inject
|
||||
public CharacterID(@Assisted int id, CharacterDAO characterDao) {
|
||||
super(id);
|
||||
this.characterDao = characterDao;
|
||||
}
|
||||
|
||||
@Override
|
||||
public L2Character getObject() {
|
||||
return characterDao.load(this);
|
||||
}
|
||||
}
|
||||
|
||||
23
src/main/java/com/l2jserver/model/id/ClanID.java
Normal file
23
src/main/java/com/l2jserver/model/id/ClanID.java
Normal file
@@ -0,0 +1,23 @@
|
||||
package com.l2jserver.model.id;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.l2jserver.db.dao.ClanDAO;
|
||||
import com.l2jserver.model.world.Clan;
|
||||
|
||||
public final class ClanID extends ObjectID<Clan> {
|
||||
/**
|
||||
* Data Access Object (DAO) for clans
|
||||
*/
|
||||
private final ClanDAO clanDao;
|
||||
|
||||
@Inject
|
||||
protected ClanID(int id, ClanDAO clanDao) {
|
||||
super(id);
|
||||
this.clanDao = clanDao;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Clan getObject() {
|
||||
return clanDao.load(this);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,55 @@
|
||||
package com.l2jserver.model.id;
|
||||
|
||||
public interface ID {
|
||||
import com.google.inject.Inject;
|
||||
|
||||
/**
|
||||
* The ID interface. Each Object or Template must be represented by an unique
|
||||
* ID.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public abstract class ID {
|
||||
/**
|
||||
* The id itself
|
||||
*/
|
||||
protected final int id;
|
||||
|
||||
@Inject
|
||||
protected ID(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the id
|
||||
*/
|
||||
public int getID() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.getClass().getSimpleName() + " [id=" + id + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + id;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
ID other = (ID) obj;
|
||||
if (id != other.id)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
24
src/main/java/com/l2jserver/model/id/ItemID.java
Normal file
24
src/main/java/com/l2jserver/model/id/ItemID.java
Normal file
@@ -0,0 +1,24 @@
|
||||
package com.l2jserver.model.id;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
import com.l2jserver.db.dao.ItemDAO;
|
||||
import com.l2jserver.model.world.Item;
|
||||
|
||||
public final class ItemID extends ObjectID<Item> {
|
||||
/**
|
||||
* Data Access Object (DAO) for items
|
||||
*/
|
||||
private final ItemDAO itemDao;
|
||||
|
||||
@Inject
|
||||
protected ItemID(@Assisted int id, ItemDAO itemDao) {
|
||||
super(id);
|
||||
this.itemDao = itemDao;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item getObject() {
|
||||
return itemDao.load(this);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,23 @@
|
||||
package com.l2jserver.model.id;
|
||||
|
||||
public interface ObjectID extends ID {
|
||||
import com.l2jserver.model.id.factory.IDFactory;
|
||||
import com.l2jserver.model.world.WorldObject;
|
||||
|
||||
/**
|
||||
* {@link ObjectID}s cannot be instantiated directly. This must be done through
|
||||
* an {@link IDFactory}. The {@link ObjectID} provides a facility
|
||||
* {@link #getObject() method} that allows easily fetch this object from
|
||||
* database without the need to directly use DAOs.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*
|
||||
* @param <T>
|
||||
* the {@link WorldObject} type
|
||||
*/
|
||||
public abstract class ObjectID<T extends WorldObject> extends ID {
|
||||
protected ObjectID(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public abstract T getObject();
|
||||
}
|
||||
|
||||
23
src/main/java/com/l2jserver/model/id/PetID.java
Normal file
23
src/main/java/com/l2jserver/model/id/PetID.java
Normal file
@@ -0,0 +1,23 @@
|
||||
package com.l2jserver.model.id;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.l2jserver.db.dao.PetDAO;
|
||||
import com.l2jserver.model.world.Pet;
|
||||
|
||||
public final class PetID extends ObjectID<Pet> {
|
||||
/**
|
||||
* Data Access Object (DAO) for pets
|
||||
*/
|
||||
private final PetDAO petDao;
|
||||
|
||||
@Inject
|
||||
protected PetID(int id, PetDAO petDao) {
|
||||
super(id);
|
||||
this.petDao = petDao;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pet getObject() {
|
||||
return petDao.load(this);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
package com.l2jserver.model.id;
|
||||
|
||||
public class SimpleID implements ID {
|
||||
|
||||
}
|
||||
@@ -1,5 +1,14 @@
|
||||
package com.l2jserver.model.id;
|
||||
|
||||
public interface TemplateID extends ID {
|
||||
|
||||
/**
|
||||
* Templates IDs, different from {@link ObjectID}s, can be repeated and are
|
||||
* defined in the template class.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*
|
||||
*/
|
||||
public final class TemplateID extends ID {
|
||||
public TemplateID(int id) {
|
||||
super(id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
package com.l2jserver.model.id.allocator;
|
||||
|
||||
import java.util.BitSet;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import com.l2jserver.util.PrimeFinder;
|
||||
|
||||
public class BitSetIDAllocator implements IDAllocator {
|
||||
/**
|
||||
* Lock to guarantee synchronization
|
||||
*/
|
||||
private Lock lock = new ReentrantLock();
|
||||
|
||||
/**
|
||||
* Available IDs
|
||||
*/
|
||||
private BitSet ids = new BitSet();
|
||||
/**
|
||||
* Amount of free ids
|
||||
*/
|
||||
private AtomicInteger freeIdCount = new AtomicInteger();
|
||||
/**
|
||||
* Next free ID
|
||||
*/
|
||||
private AtomicInteger nextId = new AtomicInteger();
|
||||
|
||||
public void init() {
|
||||
ids = new BitSet(PrimeFinder.nextPrime(100000));
|
||||
ids.clear();
|
||||
freeIdCount = new AtomicInteger(ALLOCABLE_IDS);
|
||||
|
||||
nextId = new AtomicInteger(ids.nextClearBit(0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void allocate(int id) {
|
||||
if (ids.get(id - FIRST_ID))
|
||||
throw new IDAllocatorException("ID not allocated");
|
||||
lock.lock();
|
||||
try {
|
||||
if (id < FIRST_ID)
|
||||
return;
|
||||
ids.set(id - FIRST_ID);
|
||||
nextId = new AtomicInteger(ids.nextClearBit(0));
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int allocate() {
|
||||
lock.lock();
|
||||
try {
|
||||
final int newID = nextId.get();
|
||||
ids.set(newID);
|
||||
freeIdCount.decrementAndGet();
|
||||
|
||||
int nextFree = ids.nextClearBit(newID);
|
||||
|
||||
if (nextFree < 0) {
|
||||
nextFree = ids.nextClearBit(0);
|
||||
}
|
||||
if (nextFree < 0) {
|
||||
if (ids.size() < ALLOCABLE_IDS) {
|
||||
increaseBitSetCapacity();
|
||||
} else {
|
||||
throw new IDAllocatorException("ID exhaustion");
|
||||
}
|
||||
}
|
||||
|
||||
nextId.set(nextFree);
|
||||
|
||||
return newID + FIRST_ID;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release(int id) {
|
||||
if (id < FIRST_ID)
|
||||
throw new IDAllocatorException(
|
||||
"Can't release ID, smaller then initial ID");
|
||||
if (!ids.get(id - FIRST_ID))
|
||||
throw new IDAllocatorException("ID not allocated");
|
||||
|
||||
lock.lock();
|
||||
try {
|
||||
ids.clear(id - FIRST_ID);
|
||||
freeIdCount.incrementAndGet();
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
private void increaseBitSetCapacity() {
|
||||
BitSet newBitSet = new BitSet(
|
||||
PrimeFinder.nextPrime((getAllocatedIDs() * 11) / 10));
|
||||
newBitSet.or(ids);
|
||||
ids = newBitSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAllocatedIDs() {
|
||||
return ALLOCABLE_IDS - getFreeIDs();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFreeIDs() {
|
||||
return freeIdCount.get();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.l2jserver.model.id.allocator;
|
||||
|
||||
/**
|
||||
* The ID allocator is used to alloc new ID and to release IDs that aren't used
|
||||
* anymore.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public interface IDAllocator {
|
||||
/**
|
||||
* The first ID ever allocated
|
||||
*/
|
||||
public final static int FIRST_ID = 0x10000000;
|
||||
/**
|
||||
* The last ID ever allocated
|
||||
*/
|
||||
public final static int LAST_ID = 0x7FFFFFFF;
|
||||
/**
|
||||
* Total of available IDs for allocation
|
||||
*/
|
||||
public final static int ALLOCABLE_IDS = LAST_ID - FIRST_ID;
|
||||
|
||||
/**
|
||||
* This is method is used to register IDs as used at startup time.
|
||||
*
|
||||
* @param id
|
||||
* the id
|
||||
*/
|
||||
void allocate(int id);
|
||||
|
||||
/**
|
||||
* Allocates a new ID
|
||||
*
|
||||
* @return the allocated ID value
|
||||
*/
|
||||
int allocate();
|
||||
|
||||
/**
|
||||
* Release an ID
|
||||
*
|
||||
* @param id
|
||||
* the id
|
||||
*/
|
||||
void release(int id);
|
||||
|
||||
/**
|
||||
* Get the amount of already allocated IDs
|
||||
*
|
||||
* @return allocated ids count
|
||||
*/
|
||||
int getAllocatedIDs();
|
||||
|
||||
/**
|
||||
* Get the amount of IDs remaining to be allocated
|
||||
*
|
||||
* @return free ids count
|
||||
*/
|
||||
int getFreeIDs();
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.l2jserver.model.id.allocator;
|
||||
|
||||
public class IDAllocatorException extends RuntimeException {
|
||||
private static final long serialVersionUID = 111195059766878062L;
|
||||
|
||||
public IDAllocatorException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public IDAllocatorException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public IDAllocatorException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public IDAllocatorException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package com.l2jserver.model.id.factory;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
import com.l2jserver.model.id.CharacterID;
|
||||
import com.l2jserver.model.id.allocator.IDAllocator;
|
||||
|
||||
/**
|
||||
* {@link IDFactory} for {@link CharacterID}.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class CharacterIDFactory implements ObjectIDFactory<CharacterID> {
|
||||
/**
|
||||
* The ID allocator
|
||||
*/
|
||||
private final IDAllocator allocator;
|
||||
/**
|
||||
* The Guice Factory
|
||||
*/
|
||||
private final CharacterIDGuiceFactory factory;
|
||||
|
||||
@Inject
|
||||
public CharacterIDFactory(IDAllocator allocator,
|
||||
CharacterIDGuiceFactory factory) {
|
||||
super();
|
||||
this.allocator = allocator;
|
||||
this.factory = factory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharacterID createID() {
|
||||
return createID(allocator.allocate());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharacterID createID(int id) {
|
||||
return factory.create(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy(CharacterID id) {
|
||||
allocator.release(id.getID());
|
||||
}
|
||||
|
||||
/**
|
||||
* This is an Google Guice factory. Assistect Inject extension will
|
||||
* automatically implement it and create the injected instances.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public interface CharacterIDGuiceFactory {
|
||||
/**
|
||||
* Creates a new ID instance
|
||||
*
|
||||
* @param id
|
||||
* the numeric ID
|
||||
* @return the new ID created by injection
|
||||
*/
|
||||
public CharacterID create(@Assisted int id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.l2jserver.model.id.factory;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
import com.l2jserver.model.id.ClanID;
|
||||
import com.l2jserver.model.id.allocator.IDAllocator;
|
||||
|
||||
/**
|
||||
* {@link IDFactory} for {@link ClanID}.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class ClanIDFactory implements ObjectIDFactory<ClanID> {
|
||||
/**
|
||||
* The ID allocator
|
||||
*/
|
||||
private final IDAllocator allocator;
|
||||
/**
|
||||
* The Guice factory
|
||||
*/
|
||||
private final ClanIDGuiceFactory factory;
|
||||
|
||||
@Inject
|
||||
public ClanIDFactory(IDAllocator allocator, ClanIDGuiceFactory factory) {
|
||||
super();
|
||||
this.allocator = allocator;
|
||||
this.factory = factory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClanID createID() {
|
||||
return createID(allocator.allocate());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClanID createID(int id) {
|
||||
return factory.create(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy(ClanID id) {
|
||||
allocator.release(id.getID());
|
||||
}
|
||||
|
||||
/**
|
||||
* This is an Google Guice factory. Assistect Inject extension will
|
||||
* automatically implement it and create the injected instances.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public interface ClanIDGuiceFactory {
|
||||
/**
|
||||
* Creates a new ID instance
|
||||
*
|
||||
* @param id
|
||||
* the numeric ID
|
||||
* @return the new ID created by injection
|
||||
*/
|
||||
public ClanID create(@Assisted int id);
|
||||
}
|
||||
}
|
||||
34
src/main/java/com/l2jserver/model/id/factory/IDFactory.java
Normal file
34
src/main/java/com/l2jserver/model/id/factory/IDFactory.java
Normal file
@@ -0,0 +1,34 @@
|
||||
package com.l2jserver.model.id.factory;
|
||||
|
||||
import com.l2jserver.model.id.ID;
|
||||
|
||||
/**
|
||||
* The ID factory is used to create instances of IDs. It will automatically make
|
||||
* sure the ID is free before allocating it.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public interface IDFactory<T extends ID> {
|
||||
/**
|
||||
* Generated a new ID
|
||||
*
|
||||
* @return the new ID
|
||||
*/
|
||||
T createID();
|
||||
|
||||
/**
|
||||
* Creates the ID object for an <b>EXISTING</b> ID.
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
T createID(int id);
|
||||
|
||||
/**
|
||||
* Destroy this ID. Releases this value to be used once again.
|
||||
*
|
||||
* @param id
|
||||
* the id to be destroyed.
|
||||
*/
|
||||
void destroy(T id);
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.l2jserver.model.id.factory;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Scopes;
|
||||
import com.google.inject.assistedinject.FactoryModuleBuilder;
|
||||
import com.l2jserver.model.id.allocator.BitSetIDAllocator;
|
||||
import com.l2jserver.model.id.allocator.IDAllocator;
|
||||
import com.l2jserver.model.id.factory.CharacterIDFactory.CharacterIDGuiceFactory;
|
||||
import com.l2jserver.model.id.factory.ItemIDFactory.ItemIDGuiceFactory;
|
||||
|
||||
public class IDFactoryModule extends AbstractModule {
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(IDAllocator.class).to(BitSetIDAllocator.class)
|
||||
.in(Scopes.SINGLETON);
|
||||
|
||||
bind(CharacterIDFactory.class).in(Scopes.SINGLETON);
|
||||
install(new FactoryModuleBuilder().build(CharacterIDGuiceFactory.class));
|
||||
|
||||
bind(ItemIDFactory.class).in(Scopes.SINGLETON);
|
||||
install(new FactoryModuleBuilder().build(ItemIDGuiceFactory.class));
|
||||
|
||||
// bind(ClanIDFactory.class).in(Scopes.SINGLETON);
|
||||
// install(new FactoryModuleBuilder().build(ClanIDGuiceFactory.class));
|
||||
//
|
||||
// bind(PetIDFactory.class).in(Scopes.SINGLETON);
|
||||
// install(new FactoryModuleBuilder().build(PetIDGuiceFactory.class));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.l2jserver.model.id.factory;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
import com.l2jserver.model.id.ItemID;
|
||||
import com.l2jserver.model.id.allocator.IDAllocator;
|
||||
|
||||
/**
|
||||
* {@link IDFactory} for {@link ItemID}.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class ItemIDFactory implements ObjectIDFactory<ItemID> {
|
||||
/**
|
||||
* The ID allocator
|
||||
*/
|
||||
private final IDAllocator allocator;
|
||||
/**
|
||||
* The Guice factory
|
||||
*/
|
||||
private final ItemIDGuiceFactory factory;
|
||||
|
||||
@Inject
|
||||
public ItemIDFactory(IDAllocator allocator, ItemIDGuiceFactory factory) {
|
||||
super();
|
||||
this.allocator = allocator;
|
||||
this.factory = factory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemID createID() {
|
||||
return createID(allocator.allocate());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemID createID(int id) {
|
||||
return factory.create(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy(ItemID id) {
|
||||
allocator.release(id.getID());
|
||||
}
|
||||
|
||||
/**
|
||||
* This is an Google Guice factory. Assistect Inject extension will
|
||||
* automatically implement it and create the injected instances.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public interface ItemIDGuiceFactory {
|
||||
/**
|
||||
* Creates a new ID instance
|
||||
*
|
||||
* @param id
|
||||
* the numeric ID
|
||||
* @return the new ID created by injection
|
||||
*/
|
||||
public ItemID create(@Assisted int id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package com.l2jserver.model.id.factory;
|
||||
|
||||
import com.l2jserver.model.id.ObjectID;
|
||||
|
||||
public interface ObjectIDFactory<T extends ObjectID<?>> extends IDFactory<T> {
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.l2jserver.model.id.factory;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
import com.l2jserver.model.id.PetID;
|
||||
import com.l2jserver.model.id.allocator.IDAllocator;
|
||||
|
||||
/**
|
||||
* {@link IDFactory} for {@link PetID}.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class PetIDFactory implements ObjectIDFactory<PetID> {
|
||||
/**
|
||||
* The ID allocator
|
||||
*/
|
||||
private final IDAllocator allocator;
|
||||
/**
|
||||
* The Guice factory
|
||||
*/
|
||||
private final PetIDGuiceFactory factory;
|
||||
|
||||
@Inject
|
||||
public PetIDFactory(IDAllocator allocator, PetIDGuiceFactory factory) {
|
||||
super();
|
||||
this.allocator = allocator;
|
||||
this.factory = factory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PetID createID() {
|
||||
return createID(allocator.allocate());
|
||||
}
|
||||
|
||||
@Override
|
||||
public PetID createID(int id) {
|
||||
return factory.create(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy(PetID id) {
|
||||
allocator.release(id.getID());
|
||||
}
|
||||
|
||||
/**
|
||||
* This is an Google Guice factory. Assistect Inject extension will
|
||||
* automatically implement it and create the injected instances.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public interface PetIDGuiceFactory {
|
||||
/**
|
||||
* Creates a new ID instance
|
||||
*
|
||||
* @param id
|
||||
* the numeric ID
|
||||
* @return the new ID created by injection
|
||||
*/
|
||||
public PetID create(@Assisted int id);
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,8 @@ import com.l2jserver.model.world.capability.Attacker;
|
||||
public interface Attackable extends TemplateCapability {
|
||||
void attack(Attacker source,
|
||||
com.l2jserver.model.world.capability.Attackable target);
|
||||
|
||||
public int getPhysicalDamage();
|
||||
public int getMagicalDamage();
|
||||
|
||||
int getPhysicalDamage();
|
||||
|
||||
int getMagicalDamage();
|
||||
}
|
||||
|
||||
@@ -5,7 +5,8 @@ import com.l2jserver.model.world.capability.Attacker;
|
||||
public interface Defendable extends TemplateCapability {
|
||||
void defend(Attacker source,
|
||||
com.l2jserver.model.world.capability.Attackable target);
|
||||
|
||||
public int getPhysicalDefense();
|
||||
public int getMagicalDefense();
|
||||
|
||||
int getPhysicalDefense();
|
||||
|
||||
int getMagicalDefense();
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import java.util.List;
|
||||
|
||||
import com.l2jserver.model.template.SkillTemplate;
|
||||
import com.l2jserver.model.template.capability.Attackable;
|
||||
import com.l2jserver.model.world.actor.ActorEvent;
|
||||
import com.l2jserver.model.world.actor.ActorListener;
|
||||
import com.l2jserver.model.world.capability.Actor;
|
||||
import com.l2jserver.model.world.capability.Attacker;
|
||||
@@ -124,21 +123,4 @@ public abstract class AbstractActor extends AbstractObject implements Actor {
|
||||
public void equip(Equiper equiper) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener(ActorListener listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListener(ActorListener listener) {
|
||||
listeners.remove(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatch(ActorEvent e) {
|
||||
for (final ActorListener listener : listeners) {
|
||||
listener.dispatch(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,13 +8,15 @@ import com.l2jserver.model.id.ObjectID;
|
||||
* @author Rogiel
|
||||
*/
|
||||
public abstract class AbstractObject implements WorldObject {
|
||||
protected ObjectID id;
|
||||
protected ObjectID<?> id;
|
||||
|
||||
public ObjectID getId() {
|
||||
public ObjectID<?> getID() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(ObjectID id) {
|
||||
public void setID(ObjectID<?> id) {
|
||||
if (this.id != null)
|
||||
throw new IllegalStateException("ID is already set!");
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
|
||||
71
src/main/java/com/l2jserver/model/world/Clan.java
Normal file
71
src/main/java/com/l2jserver/model/world/Clan.java
Normal file
@@ -0,0 +1,71 @@
|
||||
package com.l2jserver.model.world;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.l2jserver.model.id.CharacterID;
|
||||
import com.l2jserver.model.id.ClanID;
|
||||
import com.l2jserver.model.world.capability.Joinable;
|
||||
import com.l2jserver.model.world.capability.Listenable;
|
||||
import com.l2jserver.model.world.clan.ClanEvent;
|
||||
import com.l2jserver.model.world.clan.ClanListener;
|
||||
import com.l2jserver.model.world.clan.ClanMembers;
|
||||
import com.l2jserver.util.factory.CollectionFactory;
|
||||
|
||||
public class Clan extends AbstractObject implements
|
||||
Listenable<ClanListener, ClanEvent>, Joinable<L2Character> {
|
||||
/**
|
||||
* This clan listeners
|
||||
*/
|
||||
private final List<ClanListener> listeners = CollectionFactory
|
||||
.newList(ClanListener.class);
|
||||
|
||||
/**
|
||||
* Clan leader
|
||||
*/
|
||||
private CharacterID leaderID;
|
||||
|
||||
/**
|
||||
* Members in the clan
|
||||
*/
|
||||
private final ClanMembers members = new ClanMembers(this);
|
||||
|
||||
/**
|
||||
* Remember to save your clan!
|
||||
*/
|
||||
@Override
|
||||
public void join(L2Character member) {
|
||||
members.add(member);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void leave(L2Character member) {
|
||||
members.remove(member);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the leaderID
|
||||
*/
|
||||
public CharacterID getLeaderID() {
|
||||
return leaderID;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the leader
|
||||
*/
|
||||
public L2Character getLeader() {
|
||||
return leaderID.getObject();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param leaderID
|
||||
* the leaderID to set
|
||||
*/
|
||||
public void setLeaderID(CharacterID leaderID) {
|
||||
this.leaderID = leaderID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClanID getID() {
|
||||
return (ClanID) super.getID();
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@ package com.l2jserver.model.world;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.l2jserver.model.world.capability.Child;
|
||||
import com.l2jserver.model.id.CharacterID;
|
||||
import com.l2jserver.model.world.capability.Listenable;
|
||||
import com.l2jserver.model.world.capability.Playable;
|
||||
import com.l2jserver.model.world.capability.Spawnable;
|
||||
@@ -12,43 +12,23 @@ import com.l2jserver.util.Coordinate;
|
||||
import com.l2jserver.util.factory.CollectionFactory;
|
||||
|
||||
public class Item extends AbstractObject implements Playable, Spawnable,
|
||||
Child<Player>, Listenable<ItemListener, ItemEvent> {
|
||||
Listenable<ItemListener, ItemEvent> {
|
||||
private final List<ItemListener> listeners = CollectionFactory
|
||||
.newList(ItemListener.class);
|
||||
|
||||
private CharacterID ownerID;
|
||||
|
||||
@Override
|
||||
public void spawn(Coordinate coordinate) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener(ItemListener listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListener(ItemListener listener) {
|
||||
listeners.remove(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatch(ItemEvent e) {
|
||||
for (final ItemListener listener : listeners) {
|
||||
listener.dispatch(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSpawned() {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Player getParent() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Coordinate getPosition() {
|
||||
// TODO Auto-generated method stub
|
||||
@@ -57,6 +37,21 @@ public class Item extends AbstractObject implements Playable, Spawnable,
|
||||
|
||||
@Override
|
||||
public void setPosition(Coordinate coord) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the ownerID
|
||||
*/
|
||||
public CharacterID getOwnerID() {
|
||||
return ownerID;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ownerID
|
||||
* the ownerID to set
|
||||
*/
|
||||
public void setOwnerID(CharacterID ownerID) {
|
||||
this.ownerID = ownerID;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,137 @@
|
||||
package com.l2jserver.model.world;
|
||||
|
||||
import com.l2jserver.model.id.CharacterID;
|
||||
import com.l2jserver.model.id.ClanID;
|
||||
import com.l2jserver.model.id.PetID;
|
||||
import com.l2jserver.model.world.character.CharacterAppearance;
|
||||
import com.l2jserver.model.world.character.CharacterInventory;
|
||||
|
||||
/**
|
||||
* This class represents a playable character in Lineage II world.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class L2Character extends Player {
|
||||
/**
|
||||
* The clan id
|
||||
*/
|
||||
private ClanID clanID;
|
||||
/**
|
||||
* The pet id
|
||||
*/
|
||||
private PetID petID;
|
||||
/**
|
||||
* The character name
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* The character's status
|
||||
*/
|
||||
private boolean online;
|
||||
|
||||
/**
|
||||
* This character's inventory
|
||||
*/
|
||||
private final CharacterInventory inventory = new CharacterInventory(this);
|
||||
/**
|
||||
* The appearance of this character
|
||||
*/
|
||||
private final CharacterAppearance appearance = new CharacterAppearance(this);
|
||||
|
||||
@Override
|
||||
public CharacterID getId() {
|
||||
return (CharacterID) super.getId();
|
||||
public CharacterID getID() {
|
||||
return (CharacterID) super.getID();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the clanID
|
||||
*/
|
||||
public ClanID getClanID() {
|
||||
return clanID;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the clan
|
||||
*/
|
||||
public Clan getClan() {
|
||||
if (clanID == null)
|
||||
return null;
|
||||
return clanID.getObject();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param clanID
|
||||
* the clanID to set
|
||||
*/
|
||||
public void setClanID(ClanID clanID) {
|
||||
this.clanID = clanID;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the petID
|
||||
*/
|
||||
public PetID getPetID() {
|
||||
return petID;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the pet
|
||||
*/
|
||||
public Pet getPet() {
|
||||
if (petID == null)
|
||||
return null;
|
||||
return petID.getObject();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param petID
|
||||
* the petID to set
|
||||
*/
|
||||
public void setPetID(PetID petID) {
|
||||
this.petID = petID;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the name
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name
|
||||
* the name to set
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the online
|
||||
*/
|
||||
public boolean isOnline() {
|
||||
return online;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param online
|
||||
* the online to set
|
||||
*/
|
||||
public void setOnline(boolean online) {
|
||||
this.online = online;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the inventory
|
||||
*/
|
||||
public CharacterInventory getInventory() {
|
||||
return inventory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the appearance
|
||||
*/
|
||||
public CharacterAppearance getAppearance() {
|
||||
return appearance;
|
||||
}
|
||||
}
|
||||
|
||||
36
src/main/java/com/l2jserver/model/world/Party.java
Normal file
36
src/main/java/com/l2jserver/model/world/Party.java
Normal file
@@ -0,0 +1,36 @@
|
||||
package com.l2jserver.model.world;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.l2jserver.model.id.CharacterID;
|
||||
import com.l2jserver.model.id.ClanID;
|
||||
import com.l2jserver.model.world.capability.Joinable;
|
||||
import com.l2jserver.model.world.capability.Listenable;
|
||||
import com.l2jserver.model.world.party.PartyEvent;
|
||||
import com.l2jserver.model.world.party.PartyListener;
|
||||
import com.l2jserver.util.factory.CollectionFactory;
|
||||
|
||||
public class Party extends AbstractObject implements
|
||||
Listenable<PartyListener, PartyEvent>, Joinable<L2Character> {
|
||||
private final List<PartyListener> listeners = CollectionFactory
|
||||
.newList(PartyListener.class);
|
||||
|
||||
private final List<CharacterID> members = CollectionFactory
|
||||
.newList(CharacterID.class);
|
||||
|
||||
@Override
|
||||
public void join(L2Character member) {
|
||||
members.add(member.getID());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClanID getID() {
|
||||
return (ClanID) super.getID();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void leave(L2Character member) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,25 +1,22 @@
|
||||
package com.l2jserver.model.world;
|
||||
|
||||
import com.l2jserver.model.world.capability.Child;
|
||||
import com.l2jserver.model.id.CharacterID;
|
||||
import com.l2jserver.model.world.capability.Summonable;
|
||||
import com.l2jserver.util.Coordinate;
|
||||
|
||||
public class Pet extends Player implements Child<L2Character>, Summonable {
|
||||
@Override
|
||||
public L2Character getParent() {
|
||||
return null;
|
||||
}
|
||||
public class Pet extends Player implements Summonable {
|
||||
private CharacterID ownerID;
|
||||
|
||||
@Override
|
||||
public void teleport(Coordinate coordinate) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void summon(Coordinate coordinate) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -27,4 +24,26 @@ public class Pet extends Player implements Child<L2Character>, Summonable {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the ownerID
|
||||
*/
|
||||
public CharacterID getOwnerID() {
|
||||
return ownerID;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the owner
|
||||
*/
|
||||
public L2Character getOwner() {
|
||||
return ownerID.getObject();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ownerID
|
||||
* the ownerID to set
|
||||
*/
|
||||
public void setOwnerID(CharacterID ownerID) {
|
||||
this.ownerID = ownerID;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package com.l2jserver.model.world;
|
||||
|
||||
import com.l2jserver.game.net.Lineage2Connection;
|
||||
import com.l2jserver.model.world.capability.Actor;
|
||||
import com.l2jserver.model.world.capability.Parent;
|
||||
import com.l2jserver.model.world.capability.Playable;
|
||||
import com.l2jserver.model.world.capability.Teleportable;
|
||||
import com.l2jserver.model.world.player.PlayerTeleportEvent;
|
||||
@@ -15,28 +13,12 @@ import com.l2jserver.util.Coordinate;
|
||||
* @author Rogiel
|
||||
*/
|
||||
public abstract class Player extends AbstractActor implements Playable, Actor,
|
||||
Teleportable, Parent {
|
||||
protected Lineage2Connection connection;
|
||||
|
||||
Teleportable {
|
||||
@Override
|
||||
public void teleport(Coordinate coordinate) {
|
||||
final PlayerTeleportEvent event = new PlayerTeleportEvent(this, coordinate);
|
||||
final PlayerTeleportEvent event = new PlayerTeleportEvent(this,
|
||||
coordinate);
|
||||
this.setPosition(coordinate);
|
||||
event.dispatch();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the connection
|
||||
*/
|
||||
public Lineage2Connection getConnection() {
|
||||
return connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param connection
|
||||
* the connection to set
|
||||
*/
|
||||
public void setConnection(Lineage2Connection connection) {
|
||||
this.connection = connection;
|
||||
// event.dispatch();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,21 @@ package com.l2jserver.model.world;
|
||||
import com.l2jserver.model.id.ObjectID;
|
||||
|
||||
public interface WorldObject {
|
||||
ObjectID getId();
|
||||
/**
|
||||
* Get the object's ID
|
||||
*
|
||||
* @return the object id
|
||||
*/
|
||||
ObjectID<?> getID();
|
||||
|
||||
void setId(ObjectID id);
|
||||
/**
|
||||
* Set this object ID. Note that the ID can only be set once. Truing to
|
||||
* change an ID will thrown an {@link IllegalStateException}.
|
||||
*
|
||||
* @param id
|
||||
* the id
|
||||
* @throws IllegalStateException
|
||||
* if ID is already set
|
||||
*/
|
||||
void setID(ObjectID<?> id) throws IllegalStateException;
|
||||
}
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
package com.l2jserver.model.world.capability;
|
||||
|
||||
import com.l2jserver.model.world.AbstractObject;
|
||||
|
||||
/**
|
||||
* Defines an {@link AbstractObject} that is a child of another
|
||||
* {@link AbstractObject}.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public interface Child<P extends Parent> extends ObjectCapability {
|
||||
public P getParent();
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.l2jserver.model.world.capability;
|
||||
|
||||
import com.l2jserver.model.world.AbstractObject;
|
||||
|
||||
/**
|
||||
* Defines an {@link AbstractObject} that other objects can join to.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public interface Joinable<T> extends ObjectCapability {
|
||||
/**
|
||||
* Join an <tt>member</tt> to this object.
|
||||
*
|
||||
* @param member
|
||||
* the entering member
|
||||
*/
|
||||
void join(T member);
|
||||
|
||||
/**
|
||||
* Removes the joined <tt>member</tt> from this object
|
||||
*
|
||||
* @param member
|
||||
* the exiting member
|
||||
*/
|
||||
void leave(T member);
|
||||
}
|
||||
@@ -17,27 +17,4 @@ import com.l2jserver.model.world.event.WorldListener;
|
||||
*/
|
||||
public interface Listenable<L extends WorldListener<E>, E extends WorldEvent>
|
||||
extends ObjectCapability {
|
||||
/**
|
||||
* Adds a new listener
|
||||
*
|
||||
* @param listener
|
||||
* the listener
|
||||
*/
|
||||
void addListener(L listener);
|
||||
|
||||
/**
|
||||
* Removes an listener
|
||||
*
|
||||
* @param listener
|
||||
* the listener
|
||||
*/
|
||||
void removeListener(L listener);
|
||||
|
||||
/**
|
||||
* Don't use this method directly. It is called by the event dispatcher.
|
||||
*
|
||||
* @param e
|
||||
* the event
|
||||
*/
|
||||
void dispatch(E e);
|
||||
}
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
package com.l2jserver.model.world.capability;
|
||||
|
||||
import com.l2jserver.model.world.AbstractObject;
|
||||
|
||||
/**
|
||||
* Defines an {@link AbstractObject} that is the parent of another
|
||||
* {@link AbstractObject}.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public interface Parent extends ObjectCapability {
|
||||
}
|
||||
@@ -0,0 +1,290 @@
|
||||
package com.l2jserver.model.world.character;
|
||||
|
||||
import com.l2jserver.model.world.L2Character;
|
||||
import com.l2jserver.util.RGBColor;
|
||||
|
||||
/**
|
||||
* Defines how an character looks in-game.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class CharacterAppearance {
|
||||
/**
|
||||
* The parent character
|
||||
*/
|
||||
private final L2Character character;
|
||||
|
||||
/**
|
||||
* The character face
|
||||
*/
|
||||
private CharacterFace face;
|
||||
|
||||
/**
|
||||
* Character possible faces
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public enum CharacterFace {
|
||||
FACE1((byte) 0x00),
|
||||
|
||||
FACE2((byte) 0x01),
|
||||
|
||||
FACE3((byte) 0x02),
|
||||
|
||||
FACE4((byte) 0x03);
|
||||
|
||||
public final byte option;
|
||||
|
||||
CharacterFace(byte option) {
|
||||
this.option = option;
|
||||
}
|
||||
|
||||
public static CharacterFace fromOption(byte option) {
|
||||
for (CharacterFace face : values()) {
|
||||
if (face.option == option)
|
||||
return face;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The character hair color
|
||||
*/
|
||||
private CharacterHairColor hairColor;
|
||||
|
||||
/**
|
||||
* Character possible hair colors
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public enum CharacterHairColor {
|
||||
COLOR1((byte) 0x00),
|
||||
|
||||
COLOR2((byte) 0x01),
|
||||
|
||||
COLOR3((byte) 0x02),
|
||||
|
||||
COLOR4((byte) 0x03);
|
||||
|
||||
public final byte option;
|
||||
|
||||
CharacterHairColor(byte option) {
|
||||
this.option = option;
|
||||
}
|
||||
|
||||
public static CharacterHairColor fromOption(byte option) {
|
||||
for (CharacterHairColor color : values()) {
|
||||
if (color.option == option)
|
||||
return color;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The character hair style
|
||||
*/
|
||||
private CharacterHairStyle hairStyle;
|
||||
|
||||
/**
|
||||
* Character possible hair styles
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public enum CharacterHairStyle {
|
||||
STYLE1((byte) 0x00),
|
||||
|
||||
STYLE2((byte) 0x01),
|
||||
|
||||
STYLE3((byte) 0x02),
|
||||
|
||||
STYLE4((byte) 0x03);
|
||||
|
||||
public final byte option;
|
||||
|
||||
CharacterHairStyle(byte option) {
|
||||
this.option = option;
|
||||
}
|
||||
|
||||
public static CharacterHairStyle fromOption(byte option) {
|
||||
for (CharacterHairStyle style : values()) {
|
||||
if (style.option == option)
|
||||
return style;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The character sex
|
||||
*/
|
||||
private CharacterSex sex;
|
||||
|
||||
/**
|
||||
* Represent the sex of an character.
|
||||
* <p>
|
||||
* TODO this will be moved soon: not only characters have sex, NPC can
|
||||
* have'em too.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public enum CharacterSex {
|
||||
MALE, FEMALE;
|
||||
}
|
||||
|
||||
/**
|
||||
* An alternative name. It will be displayed in-game.
|
||||
* <p>
|
||||
* <b>This is not persisted!</b>
|
||||
*/
|
||||
private String alternativeName;
|
||||
/**
|
||||
* An alternative title. It will be displayed in-game.
|
||||
* <p>
|
||||
* <b>This is not persisted!</b>
|
||||
*/
|
||||
private String alternativeTitle;
|
||||
|
||||
/**
|
||||
* The name color
|
||||
*/
|
||||
private RGBColor nameColor = new RGBColor((byte) 0xFF, (byte) 0xFF,
|
||||
(byte) 0xFF);
|
||||
/**
|
||||
* The title color
|
||||
*/
|
||||
private RGBColor titleColor = new RGBColor((byte) 0xFF, (byte) 0xFF,
|
||||
(byte) 0x77);
|
||||
|
||||
public CharacterAppearance(L2Character character) {
|
||||
this.character = character;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the character face
|
||||
*/
|
||||
public CharacterFace getFace() {
|
||||
return face;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param face
|
||||
* the character face to set
|
||||
*/
|
||||
public void setFace(CharacterFace face) {
|
||||
this.face = face;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the hair color
|
||||
*/
|
||||
public CharacterHairColor getHairColor() {
|
||||
return hairColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param hairColor
|
||||
* the hair color to set
|
||||
*/
|
||||
public void setHairColor(CharacterHairColor hairColor) {
|
||||
this.hairColor = hairColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the hair style
|
||||
*/
|
||||
public CharacterHairStyle getHairStyle() {
|
||||
return hairStyle;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param hairStyle
|
||||
* the hair style to set
|
||||
*/
|
||||
public void setHairStyle(CharacterHairStyle hairStyle) {
|
||||
this.hairStyle = hairStyle;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the character sex
|
||||
*/
|
||||
public CharacterSex getSex() {
|
||||
return sex;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param sex
|
||||
* the character sex to set
|
||||
*/
|
||||
public void setSex(CharacterSex sex) {
|
||||
this.sex = sex;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the alternative name
|
||||
*/
|
||||
public String getAlternativeName() {
|
||||
return alternativeName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param alternativeName
|
||||
* the alternative name to set
|
||||
*/
|
||||
public void setAlternativeName(String alternativeName) {
|
||||
this.alternativeName = alternativeName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the alternative title
|
||||
*/
|
||||
public String getAlternativeTitle() {
|
||||
return alternativeTitle;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param alternativeTitle
|
||||
* the alternative title to set
|
||||
*/
|
||||
public void setAlternativeTitle(String alternativeTitle) {
|
||||
this.alternativeTitle = alternativeTitle;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the name color
|
||||
*/
|
||||
public RGBColor getNameColor() {
|
||||
return nameColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param nameColor
|
||||
* the name color to set
|
||||
*/
|
||||
public void setNameColor(RGBColor nameColor) {
|
||||
this.nameColor = nameColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the title color
|
||||
*/
|
||||
public RGBColor getTitleColor() {
|
||||
return titleColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param titleColor
|
||||
* the title color to set
|
||||
*/
|
||||
public void setTitleColor(RGBColor titleColor) {
|
||||
this.titleColor = titleColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the character
|
||||
*/
|
||||
public L2Character getCharacter() {
|
||||
return character;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.l2jserver.model.world.character;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
import com.l2jserver.model.id.CharacterID;
|
||||
import com.l2jserver.model.world.L2Character;
|
||||
import com.l2jserver.util.factory.CollectionFactory;
|
||||
|
||||
/**
|
||||
* Defines how an character looks in-game.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class CharacterFriendList implements Iterable<L2Character> {
|
||||
private final L2Character character;
|
||||
|
||||
private final Set<CharacterID> friends = CollectionFactory
|
||||
.newSet(CharacterID.class);
|
||||
|
||||
public CharacterFriendList(L2Character character) {
|
||||
this.character = character;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the character
|
||||
*/
|
||||
public L2Character getCharacter() {
|
||||
return character;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<L2Character> iterator() {
|
||||
// TODO
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.l2jserver.model.world.character;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import com.l2jserver.model.world.Item;
|
||||
import com.l2jserver.model.world.L2Character;
|
||||
import com.l2jserver.util.factory.CollectionFactory;
|
||||
|
||||
public class CharacterInventory implements Iterable<Item> {
|
||||
private final L2Character character;
|
||||
|
||||
/**
|
||||
* The items in this character inventory
|
||||
*/
|
||||
private final Set<Item> items = CollectionFactory.newSet(Item.class);
|
||||
|
||||
public CharacterInventory(L2Character character) {
|
||||
this.character = character;
|
||||
}
|
||||
|
||||
public void load(List<Item> items) {
|
||||
items.addAll(items);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the character
|
||||
*/
|
||||
public L2Character getCharacter() {
|
||||
return character;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Item> iterator() {
|
||||
return items.iterator();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.l2jserver.model.world.clan;
|
||||
|
||||
import com.l2jserver.model.world.Clan;
|
||||
import com.l2jserver.model.world.event.WorldEvent;
|
||||
|
||||
public interface ClanEvent extends WorldEvent {
|
||||
Clan getClan();
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package com.l2jserver.model.world.clan;
|
||||
|
||||
import com.l2jserver.model.world.event.WorldListener;
|
||||
|
||||
public interface ClanListener extends WorldListener<ClanEvent> {
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package com.l2jserver.model.world.clan;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import com.l2jserver.model.id.CharacterID;
|
||||
import com.l2jserver.model.world.Clan;
|
||||
import com.l2jserver.model.world.L2Character;
|
||||
import com.l2jserver.util.factory.CollectionFactory;
|
||||
|
||||
/**
|
||||
* This class handles members inside an clan
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class ClanMembers implements Iterable<CharacterID> {
|
||||
/**
|
||||
* The parent {@link Clan}
|
||||
*/
|
||||
private final Clan clan;
|
||||
|
||||
/**
|
||||
* The list of active members
|
||||
*/
|
||||
private final Set<CharacterID> members = CollectionFactory
|
||||
.newSet(CharacterID.class);
|
||||
|
||||
public ClanMembers(Clan clan) {
|
||||
this.clan = clan;
|
||||
}
|
||||
|
||||
/**
|
||||
* Effectively add this character as a clan member
|
||||
*
|
||||
* @param character
|
||||
* the character
|
||||
* @return true if add, false otherwise
|
||||
*/
|
||||
public boolean add(L2Character character) {
|
||||
return members.add(character.getID());
|
||||
}
|
||||
|
||||
/**
|
||||
* Effectively add this character as a clan member
|
||||
*
|
||||
* @param character
|
||||
* the character
|
||||
* @return true if add, false otherwise
|
||||
*/
|
||||
public boolean remove(L2Character character) {
|
||||
return members.remove(character.getID());
|
||||
}
|
||||
|
||||
/**
|
||||
* Load an list of members to this clan
|
||||
*
|
||||
* @param members
|
||||
* the list of members ids
|
||||
*/
|
||||
public void load(List<CharacterID> members) {
|
||||
this.members.addAll(members);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the clan
|
||||
*/
|
||||
public Clan getClan() {
|
||||
return clan;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<CharacterID> iterator() {
|
||||
return members.iterator();
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,10 @@
|
||||
package com.l2jserver.model.world.event;
|
||||
|
||||
import com.l2jserver.model.world.WorldObject;
|
||||
import com.l2jserver.model.world.capability.Listenable;
|
||||
|
||||
public interface WorldEvent {
|
||||
WorldObject getObject();
|
||||
|
||||
/**
|
||||
* Dispatch this event to all the objects
|
||||
*/
|
||||
void dispatch();
|
||||
Listenable<?, ?>[] getDispatchableObjects();
|
||||
}
|
||||
|
||||
@@ -10,11 +10,13 @@ package com.l2jserver.model.world.event;
|
||||
*/
|
||||
public interface WorldListener<E extends WorldEvent> {
|
||||
/**
|
||||
* Once the event call is dispatched, the listener <b>WILL NOT</b> be
|
||||
* removed. You must manually remove it from the <tt>event</tt> object.
|
||||
* Once the event call is dispatched the listener <b>WILL</b> be removed if
|
||||
* false is returned. If you wish to keep this listener, you must return
|
||||
* true.
|
||||
*
|
||||
* @param e
|
||||
* the event
|
||||
* @return true to keep listener alive
|
||||
*/
|
||||
void dispatch(E e);
|
||||
boolean dispatch(E e);
|
||||
}
|
||||
|
||||
@@ -15,6 +15,6 @@ public class IDFilter implements WorldObjectFilter<Positionable> {
|
||||
public boolean accept(Positionable other) {
|
||||
if (other == null)
|
||||
return false;
|
||||
return other.getId().equals(id);
|
||||
return other.getID().equals(id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.l2jserver.model.world.Item;
|
||||
import com.l2jserver.model.world.Player;
|
||||
import com.l2jserver.model.world.WorldObject;
|
||||
import com.l2jserver.model.world.capability.Actor;
|
||||
import com.l2jserver.model.world.capability.Listenable;
|
||||
import com.l2jserver.model.world.player.PlayerEvent;
|
||||
|
||||
public class ItemDropEvent implements ItemEvent, PlayerEvent {
|
||||
@@ -30,15 +31,13 @@ public class ItemDropEvent implements ItemEvent, PlayerEvent {
|
||||
return item;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatch() {
|
||||
item.dispatch(this);
|
||||
if (player != null)
|
||||
player.dispatch(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Actor getActor() {
|
||||
return player;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Listenable<?, ?>[] getDispatchableObjects() {
|
||||
return new Listenable<?, ?>[] { player, item };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.l2jserver.model.world.party;
|
||||
|
||||
import com.l2jserver.model.world.Clan;
|
||||
import com.l2jserver.model.world.event.WorldEvent;
|
||||
|
||||
public interface PartyEvent extends WorldEvent {
|
||||
Clan getClan();
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package com.l2jserver.model.world.party;
|
||||
|
||||
import com.l2jserver.model.world.event.WorldListener;
|
||||
|
||||
public interface PartyListener extends WorldListener<PartyEvent> {
|
||||
}
|
||||
@@ -5,10 +5,10 @@ import com.l2jserver.model.world.actor.ActorListener;
|
||||
|
||||
public abstract class PlayerListener implements ActorListener {
|
||||
@Override
|
||||
public void dispatch(ActorEvent e) {
|
||||
public boolean dispatch(ActorEvent e) {
|
||||
if (!(e instanceof PlayerEvent))
|
||||
return;
|
||||
dispatch((PlayerEvent) e);
|
||||
return false;
|
||||
return dispatch((PlayerEvent) e);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -18,5 +18,5 @@ public abstract class PlayerListener implements ActorListener {
|
||||
* @param e
|
||||
* the event
|
||||
*/
|
||||
protected abstract void dispatch(PlayerEvent e);
|
||||
protected abstract boolean dispatch(PlayerEvent e);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.l2jserver.model.world.player;
|
||||
|
||||
import com.l2jserver.model.world.Player;
|
||||
import com.l2jserver.model.world.capability.Actor;
|
||||
import com.l2jserver.model.world.capability.Listenable;
|
||||
import com.l2jserver.model.world.capability.Spawnable;
|
||||
import com.l2jserver.model.world.event.SpawnEvent;
|
||||
import com.l2jserver.util.Coordinate;
|
||||
@@ -14,12 +15,6 @@ public class PlayerSpawnEvent implements PlayerEvent, SpawnEvent {
|
||||
this.player = player;
|
||||
this.coordinate = coordinate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatch() {
|
||||
if (player != null)
|
||||
player.dispatch(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Spawnable getObject() {
|
||||
@@ -40,4 +35,9 @@ public class PlayerSpawnEvent implements PlayerEvent, SpawnEvent {
|
||||
public Actor getActor() {
|
||||
return player;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Listenable<?, ?>[] getDispatchableObjects() {
|
||||
return new Listenable<?, ?>[] { player };
|
||||
}
|
||||
}
|
||||
|
||||
20
src/main/java/com/l2jserver/service/cache/CacheService.java
vendored
Normal file
20
src/main/java/com/l2jserver/service/cache/CacheService.java
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
package com.l2jserver.service.cache;
|
||||
|
||||
import com.l2jserver.service.Service;
|
||||
|
||||
/**
|
||||
* This is an transparent Cache system. It proxies an interface implementing
|
||||
* {@link Cacheable}. Once the first call is done through the proxy, the result
|
||||
* is cached in the underlying cache engine. When the second and sucedind calls
|
||||
* are made the cache is looked up, if a match (method and arguments pair) is
|
||||
* found, this result is returned.
|
||||
* <p>
|
||||
* If you do not desire to cache an method, annotate it with
|
||||
* {@link IgnoreCaching}
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*
|
||||
*/
|
||||
public interface CacheService extends Service {
|
||||
<T extends Cacheable> T decorate(Class<T> interfaceType, T instance);
|
||||
}
|
||||
5
src/main/java/com/l2jserver/service/cache/Cacheable.java
vendored
Normal file
5
src/main/java/com/l2jserver/service/cache/Cacheable.java
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
package com.l2jserver.service.cache;
|
||||
|
||||
public interface Cacheable {
|
||||
|
||||
}
|
||||
16
src/main/java/com/l2jserver/service/cache/IgnoreCaching.java
vendored
Normal file
16
src/main/java/com/l2jserver/service/cache/IgnoreCaching.java
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
package com.l2jserver.service.cache;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
@Documented
|
||||
/**
|
||||
* Indicate to the proxy that this method should not be cached.
|
||||
*/
|
||||
public @interface IgnoreCaching {
|
||||
}
|
||||
94
src/main/java/com/l2jserver/service/cache/SimpleCacheService.java
vendored
Normal file
94
src/main/java/com/l2jserver/service/cache/SimpleCacheService.java
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
package com.l2jserver.service.cache;
|
||||
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
||||
import com.l2jserver.service.ServiceStartException;
|
||||
import com.l2jserver.service.ServiceStopException;
|
||||
import com.l2jserver.util.factory.CollectionFactory;
|
||||
|
||||
public class SimpleCacheService implements CacheService {
|
||||
private final Map<MethodInvocation, Object> cache = CollectionFactory
|
||||
.newWeakMap(MethodInvocation.class, Object.class);
|
||||
|
||||
@Override
|
||||
public void start() throws ServiceStartException {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Cacheable> T decorate(final Class<T> interfaceType,
|
||||
final T instance) {
|
||||
if (!interfaceType.isInterface())
|
||||
return null;
|
||||
@SuppressWarnings("unchecked")
|
||||
final T proxy = (T) Proxy.newProxyInstance(this.getClass()
|
||||
.getClassLoader(), new Class[] { interfaceType },
|
||||
new InvocationHandler() {
|
||||
@Override
|
||||
public Object invoke(Object proxy, Method method,
|
||||
Object[] args) throws Throwable {
|
||||
if (method.isAnnotationPresent(IgnoreCaching.class))
|
||||
return method.invoke(instance, args);
|
||||
final MethodInvocation invocation = new MethodInvocation(
|
||||
method, args);
|
||||
Object result = cache.get(invocation);
|
||||
if (result == null) {
|
||||
result = method.invoke(instance, args);
|
||||
cache.put(invocation, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
});
|
||||
return proxy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() throws ServiceStopException {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
private class MethodInvocation {
|
||||
private final Method method;
|
||||
private final Object[] args;
|
||||
|
||||
public MethodInvocation(Method method, Object[] args) {
|
||||
this.method = method;
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + Arrays.hashCode(args);
|
||||
result = prime * result
|
||||
+ ((method == null) ? 0 : method.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
MethodInvocation other = (MethodInvocation) obj;
|
||||
if (!Arrays.equals(args, other.args))
|
||||
return false;
|
||||
if (method == null) {
|
||||
if (other.method != null)
|
||||
return false;
|
||||
} else if (!method.equals(other.method))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,9 @@
|
||||
package com.l2jserver.service.game.world;
|
||||
|
||||
import com.l2jserver.model.id.ObjectID;
|
||||
import com.l2jserver.model.world.capability.Listenable;
|
||||
import com.l2jserver.model.world.event.WorldEvent;
|
||||
import com.l2jserver.model.world.event.WorldListener;
|
||||
|
||||
/**
|
||||
* This event dispatcher notify listeners that an certain event occured in their
|
||||
@@ -18,4 +21,64 @@ public interface WorldEventDispatcher {
|
||||
* the event
|
||||
*/
|
||||
void dispatch(WorldEvent event);
|
||||
|
||||
/**
|
||||
* Adds a new <tt>listener</tt> to <tt>object</tt>
|
||||
*
|
||||
* @param <E>
|
||||
* the event type
|
||||
* @param <L>
|
||||
* the listener type
|
||||
* @param object
|
||||
* the object to listen to
|
||||
* @param listener
|
||||
* the listener
|
||||
*/
|
||||
<E extends WorldEvent, L extends WorldListener<E>> void addListener(
|
||||
Listenable<L, E> object, WorldListener<E> listener);
|
||||
|
||||
/**
|
||||
* Adds a new <tt>listener</tt> to object with id <tt>id</tt>
|
||||
*
|
||||
* @param <E>
|
||||
* the event type
|
||||
* @param <L>
|
||||
* the listener type
|
||||
* @param id
|
||||
* the object id to listen to
|
||||
* @param listener
|
||||
* the listener
|
||||
*/
|
||||
<E extends WorldEvent, L extends WorldListener<E>> void addListener(
|
||||
ObjectID<? extends Listenable<L, E>> id, WorldListener<E> listener);
|
||||
|
||||
/**
|
||||
* Removes an existing <tt>listener</tt> from <tt>object</tt>
|
||||
*
|
||||
* @param <E>
|
||||
* the event type
|
||||
* @param <L>
|
||||
* the listener type
|
||||
* @param object
|
||||
* the object to listen to
|
||||
* @param listener
|
||||
* the listener
|
||||
*/
|
||||
<E extends WorldEvent, L extends WorldListener<E>> void removeListener(
|
||||
Listenable<L, E> object, WorldListener<E> listener);
|
||||
|
||||
/**
|
||||
* Removes an existing <tt>listener</tt> from the object with id <tt>id</tt>
|
||||
*
|
||||
* @param <E>
|
||||
* the event type
|
||||
* @param <L>
|
||||
* the listener type
|
||||
* @param id
|
||||
* the object id to listen to
|
||||
* @param listener
|
||||
* the listener
|
||||
*/
|
||||
<E extends WorldEvent, L extends WorldListener<E>> void removeListener(
|
||||
ObjectID<? extends Listenable<L, E>> id, WorldListener<E> listener);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
package com.l2jserver.service.game.world;
|
||||
|
||||
import java.util.Queue;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
import com.l2jserver.model.id.ObjectID;
|
||||
import com.l2jserver.model.world.capability.Listenable;
|
||||
import com.l2jserver.model.world.event.WorldEvent;
|
||||
import com.l2jserver.model.world.event.WorldListener;
|
||||
import com.l2jserver.util.factory.CollectionFactory;
|
||||
|
||||
/**
|
||||
* {@link WorldEventDispatcher} implementation
|
||||
@@ -8,8 +16,137 @@ import com.l2jserver.model.world.event.WorldEvent;
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class WorldEventDispatcherImpl implements WorldEventDispatcher {
|
||||
private final Timer timer = new Timer();
|
||||
|
||||
private Queue<ListenerIDPair> listeners = CollectionFactory
|
||||
.newConcurrentQueue(ListenerIDPair.class);
|
||||
private Queue<WorldEvent> events = CollectionFactory
|
||||
.newConcurrentQueue(WorldEvent.class);
|
||||
|
||||
public WorldEventDispatcherImpl() {
|
||||
timer.scheduleAtFixedRate(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
final WorldEvent event = events.poll();
|
||||
if (event == null)
|
||||
return;
|
||||
try {
|
||||
doDispatch(event);
|
||||
} catch (Throwable t) {
|
||||
}
|
||||
}
|
||||
}, 0, 50);
|
||||
}
|
||||
|
||||
public void dispatch(WorldEvent event) {
|
||||
// TODO implement threaded model
|
||||
event.dispatch();
|
||||
events.add(event);
|
||||
}
|
||||
|
||||
public void doDispatch(WorldEvent event) {
|
||||
final Listenable<?, ?>[] objects = event.getDispatchableObjects();
|
||||
for (final ListenerIDPair pair : listeners) {
|
||||
for (Listenable<?, ?> obj : objects) {
|
||||
if (obj == null)
|
||||
continue;
|
||||
if (!pair.testDispatch(obj.getID()))
|
||||
continue;
|
||||
try {
|
||||
if (pair.dispatch(event))
|
||||
continue;
|
||||
} catch (ClassCastException e) {
|
||||
}
|
||||
listeners.remove(pair);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <E extends WorldEvent, L extends WorldListener<E>> void addListener(
|
||||
Listenable<L, E> object, WorldListener<E> listener) {
|
||||
listeners.add(new ListenerIDPair(object.getID(),
|
||||
(WorldListener<WorldEvent>) listener));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <E extends WorldEvent, L extends WorldListener<E>> void addListener(
|
||||
ObjectID<? extends Listenable<L, E>> id, WorldListener<E> listener) {
|
||||
listeners.add(new ListenerIDPair(id,
|
||||
(WorldListener<WorldEvent>) listener));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <E extends WorldEvent, L extends WorldListener<E>> void removeListener(
|
||||
Listenable<L, E> object, WorldListener<E> listener) {
|
||||
listeners.remove(new ListenerIDPair(object.getID(),
|
||||
(WorldListener<WorldEvent>) listener));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <E extends WorldEvent, L extends WorldListener<E>> void removeListener(
|
||||
ObjectID<? extends Listenable<L, E>> id, WorldListener<E> listener) {
|
||||
listeners.remove(new ListenerIDPair(id,
|
||||
(WorldListener<WorldEvent>) listener));
|
||||
}
|
||||
|
||||
private class ListenerIDPair {
|
||||
private ObjectID<?> ID;
|
||||
private WorldListener<WorldEvent> listener;
|
||||
|
||||
public ListenerIDPair(ObjectID<?> ID, WorldListener<WorldEvent> listener) {
|
||||
super();
|
||||
this.ID = ID;
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
public boolean testDispatch(ObjectID<?> id) {
|
||||
return id.equals(this.ID);
|
||||
}
|
||||
|
||||
public boolean dispatch(WorldEvent e) {
|
||||
return listener.dispatch(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + getOuterType().hashCode();
|
||||
result = prime * result + ((ID == null) ? 0 : ID.hashCode());
|
||||
result = prime * result
|
||||
+ ((listener == null) ? 0 : listener.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
ListenerIDPair other = (ListenerIDPair) obj;
|
||||
if (!getOuterType().equals(other.getOuterType()))
|
||||
return false;
|
||||
if (ID == null) {
|
||||
if (other.ID != null)
|
||||
return false;
|
||||
} else if (!ID.equals(other.ID))
|
||||
return false;
|
||||
if (listener == null) {
|
||||
if (other.listener != null)
|
||||
return false;
|
||||
} else if (!listener.equals(other.listener))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
private WorldEventDispatcherImpl getOuterType() {
|
||||
return WorldEventDispatcherImpl.this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Injector;
|
||||
import com.l2jserver.game.net.Lineage2Connection;
|
||||
import com.l2jserver.game.net.Lineage2PipelineFactory;
|
||||
import com.l2jserver.service.configuration.ConfigurationService;
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.l2jserver.service.network;
|
||||
|
||||
import com.l2jserver.game.net.Lineage2Connection;
|
||||
import com.l2jserver.service.Service;
|
||||
|
||||
public interface NetworkService extends Service {
|
||||
|
||||
158
src/main/java/com/l2jserver/util/PrimeFinder.java
Normal file
158
src/main/java/com/l2jserver/util/PrimeFinder.java
Normal file
@@ -0,0 +1,158 @@
|
||||
// Copyright (c) 1999 CERN - European Organization for Nuclear Research.
|
||||
|
||||
// Permission to use, copy, modify, distribute and sell this software
|
||||
// and its documentation for any purpose is hereby granted without fee,
|
||||
// provided that the above copyright notice appear in all copies and
|
||||
// that both that copyright notice and this permission notice appear in
|
||||
// supporting documentation. CERN makes no representations about the
|
||||
// suitability of this software for any purpose. It is provided "as is"
|
||||
// without expressed or implied warranty.
|
||||
package com.l2jserver.util;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/*
|
||||
* Modified for Trove to use the java.util.Arrays sort/search
|
||||
* algorithms instead of those provided with colt.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Used to keep hash table capacities prime numbers.
|
||||
* Not of interest for users; only for implementors of hashtables.
|
||||
*
|
||||
* <p>Choosing prime numbers as hash table capacities is a good idea
|
||||
* to keep them working fast, particularly under hash table
|
||||
* expansions.
|
||||
*
|
||||
* <p>However, JDK 1.2, JGL 3.1 and many other toolkits do nothing to
|
||||
* keep capacities prime. This class provides efficient means to
|
||||
* choose prime capacities.
|
||||
*
|
||||
* <p>Choosing a prime is <tt>O(log 300)</tt> (binary search in a list
|
||||
* of 300 ints). Memory requirements: 1 KB static memory.
|
||||
*
|
||||
* @author wolfgang.hoschek@cern.ch
|
||||
* @version 1.0, 09/24/99
|
||||
*/
|
||||
public final class PrimeFinder {
|
||||
/**
|
||||
* The largest prime this class can generate; currently equal to
|
||||
* <tt>Integer.MAX_VALUE</tt>.
|
||||
*/
|
||||
public static final int LARGEST_PRIME = Integer.MAX_VALUE; //yes, it is prime.
|
||||
|
||||
/**
|
||||
* The prime number list consists of 11 chunks.
|
||||
*
|
||||
* Each chunk contains prime numbers.
|
||||
*
|
||||
* A chunk starts with a prime P1. The next element is a prime
|
||||
* P2. P2 is the smallest prime for which holds: P2 >= 2*P1.
|
||||
*
|
||||
* The next element is P3, for which the same holds with respect
|
||||
* to P2, and so on.
|
||||
*
|
||||
* Chunks are chosen such that for any desired capacity >= 1000
|
||||
* the list includes a prime number <= desired capacity * 1.11.
|
||||
*
|
||||
* Therefore, primes can be retrieved which are quite close to any
|
||||
* desired capacity, which in turn avoids wasting memory.
|
||||
*
|
||||
* For example, the list includes
|
||||
* 1039,1117,1201,1277,1361,1439,1523,1597,1759,1907,2081.
|
||||
*
|
||||
* So if you need a prime >= 1040, you will find a prime <=
|
||||
* 1040*1.11=1154.
|
||||
*
|
||||
* Chunks are chosen such that they are optimized for a hashtable
|
||||
* growthfactor of 2.0;
|
||||
*
|
||||
* If your hashtable has such a growthfactor then, after initially
|
||||
* "rounding to a prime" upon hashtable construction, it will
|
||||
* later expand to prime capacities such that there exist no
|
||||
* better primes.
|
||||
*
|
||||
* In total these are about 32*10=320 numbers -> 1 KB of static
|
||||
* memory needed.
|
||||
*
|
||||
* If you are stingy, then delete every second or fourth chunk.
|
||||
*/
|
||||
|
||||
private static final int[] PRIME_CAPACITIES = {
|
||||
//chunk #0
|
||||
LARGEST_PRIME,
|
||||
|
||||
//chunk #1
|
||||
5,11,23,47,97,197,397,797,1597,3203,6421,12853,25717,51437,102877,205759,
|
||||
411527,823117,1646237,3292489,6584983,13169977,26339969,52679969,105359939,
|
||||
210719881,421439783,842879579,1685759167,
|
||||
|
||||
//chunk #2
|
||||
433,877,1759,3527,7057,14143,28289,56591,113189,226379,452759,905551,1811107,
|
||||
3622219,7244441,14488931,28977863,57955739,115911563,231823147,463646329,927292699,
|
||||
1854585413,
|
||||
|
||||
//chunk #3
|
||||
953,1907,3821,7643,15287,30577,61169,122347,244703,489407,978821,1957651,3915341,
|
||||
7830701,15661423,31322867,62645741,125291483,250582987,501165979,1002331963,
|
||||
2004663929,
|
||||
|
||||
//chunk #4
|
||||
1039,2081,4177,8363,16729,33461,66923,133853,267713,535481,1070981,2141977,4283963,
|
||||
8567929,17135863,34271747,68543509,137087021,274174111,548348231,1096696463,
|
||||
|
||||
//chunk #5
|
||||
31,67,137,277,557,1117,2237,4481,8963,17929,35863,71741,143483,286973,573953,
|
||||
1147921,2295859,4591721,9183457,18366923,36733847,73467739,146935499,293871013,
|
||||
587742049,1175484103,
|
||||
|
||||
//chunk #6
|
||||
599,1201,2411,4831,9677,19373,38747,77509,155027,310081,620171,1240361,2480729,
|
||||
4961459,9922933,19845871,39691759,79383533,158767069,317534141,635068283,1270136683,
|
||||
|
||||
//chunk #7
|
||||
311,631,1277,2557,5119,10243,20507,41017,82037,164089,328213,656429,1312867,
|
||||
2625761,5251529,10503061,21006137,42012281,84024581,168049163,336098327,672196673,
|
||||
1344393353,
|
||||
|
||||
//chunk #8
|
||||
3,7,17,37,79,163,331,673,1361,2729,5471,10949,21911,43853,87719,175447,350899,
|
||||
701819,1403641,2807303,5614657,11229331,22458671,44917381,89834777,179669557,
|
||||
359339171,718678369,1437356741,
|
||||
|
||||
//chunk #9
|
||||
43,89,179,359,719,1439,2879,5779,11579,23159,46327,92657,185323,370661,741337,
|
||||
1482707,2965421,5930887,11861791,23723597,47447201,94894427,189788857,379577741,
|
||||
759155483,1518310967,
|
||||
|
||||
//chunk #10
|
||||
379,761,1523,3049,6101,12203,24407,48817,97649,195311,390647,781301,1562611,
|
||||
3125257,6250537,12501169,25002389,50004791,100009607,200019221,400038451,800076929,
|
||||
1600153859
|
||||
};
|
||||
|
||||
static { //initializer
|
||||
// The above prime numbers are formatted for human readability.
|
||||
// To find numbers fast, we sort them once and for all.
|
||||
|
||||
Arrays.sort(PRIME_CAPACITIES);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a prime number which is <code>>= desiredCapacity</code>
|
||||
* and very close to <code>desiredCapacity</code> (within 11% if
|
||||
* <code>desiredCapacity >= 1000</code>).
|
||||
*
|
||||
* @param desiredCapacity the capacity desired by the user.
|
||||
* @return the capacity which should be used for a hashtable.
|
||||
*/
|
||||
public static final int nextPrime(int desiredCapacity) {
|
||||
int i = Arrays.binarySearch(PRIME_CAPACITIES, desiredCapacity);
|
||||
if (i<0) {
|
||||
// desired capacity not found, choose next prime greater
|
||||
// than desired capacity
|
||||
i = -i -1; // remember the semantics of binarySearch...
|
||||
}
|
||||
return PRIME_CAPACITIES[i];
|
||||
}
|
||||
}
|
||||
38
src/main/java/com/l2jserver/util/RGBColor.java
Normal file
38
src/main/java/com/l2jserver/util/RGBColor.java
Normal file
@@ -0,0 +1,38 @@
|
||||
package com.l2jserver.util;
|
||||
|
||||
public class RGBColor {
|
||||
private final byte red;
|
||||
private final byte green;
|
||||
private final byte blue;
|
||||
|
||||
public RGBColor(byte r, byte g, byte b) {
|
||||
this.red = r;
|
||||
this.green = g;
|
||||
this.blue = b;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the red
|
||||
*/
|
||||
public byte getR() {
|
||||
return red;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the green
|
||||
*/
|
||||
public byte getG() {
|
||||
return green;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the blue
|
||||
*/
|
||||
public byte getB() {
|
||||
return blue;
|
||||
}
|
||||
|
||||
public byte[] toByteArray() {
|
||||
return new byte[] { red, green, blue };
|
||||
}
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
package com.l2jserver.util.factory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
/**
|
||||
* Factory class to create {@link Collection} instances.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class CollectionFactory {
|
||||
/**
|
||||
* Creates a new list of type <tt>T</tt>
|
||||
*
|
||||
* @param <T>
|
||||
* the type
|
||||
* @param type
|
||||
* the type
|
||||
* @return the created list
|
||||
*/
|
||||
public static final <T> List<T> newList(Class<T> type) {
|
||||
return new ArrayList<T>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new set of type <tt>T</tt>
|
||||
*
|
||||
* @param <T>
|
||||
* the type
|
||||
* @param type
|
||||
* the type
|
||||
* @return the created set
|
||||
*/
|
||||
public static final <T> Set<T> newSet(Class<T> type) {
|
||||
return new HashSet<T>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new weak map.
|
||||
*
|
||||
* @param <K>
|
||||
* the key type
|
||||
* @param <V>
|
||||
* the value type
|
||||
* @param key
|
||||
* the key type class
|
||||
* @param value
|
||||
* the value type class
|
||||
* @return the new map
|
||||
*/
|
||||
public static final <K, V> Map<K, V> newWeakMap(Class<K> key, Class<V> value) {
|
||||
return new WeakHashMap<K, V>();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user