mirror of
https://github.com/Rogiel/l2jserver2
synced 2025-12-09 17:02:53 +00:00
Change-Id: I0000000000000000000000000000000000000000
Change-Id: I8636776eaf000fcdfb528cc403710f6d6ee9e73e Change-Id: Iebc523681d07ecd6d7b7e89343b29a8034558f94
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
package com.l2jserver;
|
||||
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.l2jserver.db.dao.DAOModuleMySQL5;
|
||||
import com.l2jserver.model.id.factory.IDFactoryModule;
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
package com.l2jserver;
|
||||
|
||||
import org.apache.log4j.BasicConfigurator;
|
||||
|
||||
import com.l2jserver.routines.GameServerInitializationRoutine;
|
||||
|
||||
public class L2JGameServerMain {
|
||||
/**
|
||||
* @param args
|
||||
* @throws InterruptedException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public static void main(String[] args) throws InterruptedException {
|
||||
BasicConfigurator.configure();
|
||||
|
||||
final L2JGameServer server = new L2JGameServer();
|
||||
try {
|
||||
server.getInjector()
|
||||
@@ -16,7 +20,7 @@ public class L2JGameServerMain {
|
||||
System.out.println("GameServer could not be started!");
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
Thread.sleep(60 * 60 * 1000);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ import com.l2jserver.model.world.L2Character;
|
||||
public class Lineage2Connection {
|
||||
private final Channel channel;
|
||||
private L2Character character;
|
||||
private Lineage2Session session;
|
||||
|
||||
public Lineage2Connection(Channel channel) {
|
||||
this.channel = channel;
|
||||
@@ -44,6 +45,23 @@ public class Lineage2Connection {
|
||||
this.character = character;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the session
|
||||
*/
|
||||
public Lineage2Session getSession() {
|
||||
return session;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param session
|
||||
* the session to set
|
||||
*/
|
||||
public void setSession(Lineage2Session session) {
|
||||
if (this.session != null)
|
||||
throw new IllegalStateException("Session is already set!");
|
||||
this.session = session;
|
||||
}
|
||||
|
||||
public Channel getChannel() {
|
||||
return channel;
|
||||
}
|
||||
|
||||
55
src/main/java/com/l2jserver/game/net/Lineage2Session.java
Normal file
55
src/main/java/com/l2jserver/game/net/Lineage2Session.java
Normal file
@@ -0,0 +1,55 @@
|
||||
package com.l2jserver.game.net;
|
||||
|
||||
public class Lineage2Session {
|
||||
private final String username;
|
||||
|
||||
private final int playKey1;
|
||||
private final int playKey2;
|
||||
|
||||
private final int loginKey1;
|
||||
private final int loginKey2;
|
||||
|
||||
public Lineage2Session(String username, int playOK1, int playOK2,
|
||||
int loginOK1, int loginOK2) {
|
||||
this.username = username;
|
||||
this.playKey1 = playOK1;
|
||||
this.playKey2 = playOK2;
|
||||
this.loginKey1 = loginOK1;
|
||||
this.loginKey2 = loginOK2;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the username
|
||||
*/
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the playKey1
|
||||
*/
|
||||
public int getPlayKey1() {
|
||||
return playKey1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the playKey2
|
||||
*/
|
||||
public int getPlayKey2() {
|
||||
return playKey2;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the loginKey1
|
||||
*/
|
||||
public int getLoginKey1() {
|
||||
return loginKey1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the loginKey2
|
||||
*/
|
||||
public int getLoginKey2() {
|
||||
return loginKey2;
|
||||
}
|
||||
}
|
||||
@@ -14,14 +14,14 @@ public class Lineage2Decrypter extends OneToOneDecoder {
|
||||
private final byte[] key = new byte[16];
|
||||
|
||||
@Override
|
||||
protected synchronized Object decode(ChannelHandlerContext ctx, Channel channel,
|
||||
Object msg) throws Exception {
|
||||
protected synchronized Object decode(ChannelHandlerContext ctx,
|
||||
Channel channel, Object msg) throws Exception {
|
||||
if (!(msg instanceof ChannelBuffer))
|
||||
return msg;
|
||||
if (!enabled)
|
||||
return msg;
|
||||
final ChannelBuffer buffer = (ChannelBuffer) msg;
|
||||
|
||||
|
||||
final int offset = buffer.readerIndex();
|
||||
final int size = buffer.readableBytes();
|
||||
int temp = 0;
|
||||
@@ -45,7 +45,7 @@ public class Lineage2Decrypter extends OneToOneDecoder {
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
public byte[] enable() {
|
||||
byte[] key = BlowFishKeygen.getRandomKey();
|
||||
this.setKey(key);
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.l2jserver.game.net.codec;
|
||||
|
||||
import org.jboss.netty.buffer.ChannelBuffer;
|
||||
import org.jboss.netty.buffer.ChannelBuffers;
|
||||
import org.jboss.netty.channel.Channel;
|
||||
import org.jboss.netty.channel.ChannelHandlerContext;
|
||||
import org.jboss.netty.handler.codec.oneone.OneToOneEncoder;
|
||||
@@ -13,17 +12,15 @@ public class Lineage2Encrypter extends OneToOneEncoder {
|
||||
private final byte[] key = new byte[16];
|
||||
|
||||
@Override
|
||||
protected synchronized Object encode(ChannelHandlerContext ctx, Channel channel,
|
||||
Object msg) throws Exception {
|
||||
protected synchronized Object encode(ChannelHandlerContext ctx,
|
||||
Channel channel, Object msg) throws Exception {
|
||||
if (!(msg instanceof ChannelBuffer))
|
||||
return msg;
|
||||
if (!enabled)
|
||||
return msg;
|
||||
final ChannelBuffer buffer = (ChannelBuffer) msg;
|
||||
|
||||
System.out.println(ChannelBuffers.hexDump(buffer));
|
||||
|
||||
final int offset = buffer.readerIndex() + 2; //skip header
|
||||
final int offset = buffer.readerIndex() + 2; // skip header
|
||||
final int size = buffer.readableBytes() - 2;
|
||||
int temp = 0;
|
||||
for (int i = 0; i < size; i++) {
|
||||
|
||||
@@ -7,10 +7,15 @@ import org.jboss.netty.buffer.ChannelBuffers;
|
||||
import org.jboss.netty.channel.Channel;
|
||||
import org.jboss.netty.channel.ChannelHandlerContext;
|
||||
import org.jboss.netty.handler.codec.frame.FrameDecoder;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class Lineage2FrameDecoder extends FrameDecoder {
|
||||
private static final int HEADER_SIZE = 2;
|
||||
|
||||
private static final Logger logger = LoggerFactory
|
||||
.getLogger(Lineage2FrameDecoder.class);
|
||||
|
||||
@Override
|
||||
protected Object decode(ChannelHandlerContext ctx, Channel channel,
|
||||
ChannelBuffer oldBuffer) throws Exception {
|
||||
@@ -19,12 +24,13 @@ public class Lineage2FrameDecoder extends FrameDecoder {
|
||||
ChannelBuffer buffer = ChannelBuffers.wrappedBuffer(oldBuffer
|
||||
.toByteBuffer().order(ByteOrder.LITTLE_ENDIAN));
|
||||
|
||||
logger.debug("Received frame segment: {}",
|
||||
ChannelBuffers.hexDump(buffer));
|
||||
|
||||
buffer.markReaderIndex();
|
||||
final int pending = buffer.readUnsignedShort() - HEADER_SIZE;
|
||||
if (pending == 0) {
|
||||
if (pending == 0)
|
||||
return null;
|
||||
}
|
||||
|
||||
if (buffer.readableBytes() < pending) {
|
||||
buffer.resetReaderIndex();
|
||||
return null;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.l2jserver.game.net.codec;
|
||||
|
||||
import org.jboss.netty.buffer.ChannelBuffer;
|
||||
import org.jboss.netty.buffer.ChannelBuffers;
|
||||
import org.jboss.netty.channel.Channel;
|
||||
import org.jboss.netty.channel.ChannelHandlerContext;
|
||||
import org.jboss.netty.handler.codec.oneone.OneToOneEncoder;
|
||||
@@ -13,10 +12,8 @@ public class Lineage2FrameEncoder extends OneToOneEncoder {
|
||||
if (!(msg instanceof ChannelBuffer))
|
||||
return msg;
|
||||
final ChannelBuffer buffer = (ChannelBuffer) msg;
|
||||
buffer.setShort(0, buffer.readableBytes() - 2);
|
||||
|
||||
System.out.println(ChannelBuffers.hexDump(buffer));
|
||||
|
||||
buffer.setShort(0, buffer.readableBytes());
|
||||
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,11 @@ import com.google.inject.Inject;
|
||||
import com.google.inject.Injector;
|
||||
import com.l2jserver.game.net.packet.ClientPacket;
|
||||
import com.l2jserver.game.net.packet.client.AuthLoginPacket;
|
||||
import com.l2jserver.game.net.packet.client.CharacterCreatePacket;
|
||||
import com.l2jserver.game.net.packet.client.LogoutPacket;
|
||||
import com.l2jserver.game.net.packet.client.ProtocolVersionPacket;
|
||||
import com.l2jserver.game.net.packet.client.RequestGotoLobby;
|
||||
import com.l2jserver.game.net.packet.client.RequestNewCharacterPacket;
|
||||
|
||||
public class Lineage2PacketReader extends OneToOneDecoder {
|
||||
private final Injector injector;
|
||||
@@ -45,12 +49,30 @@ public class Lineage2PacketReader extends OneToOneDecoder {
|
||||
private Class<? extends ClientPacket> getPacketClass(ChannelBuffer buffer) {
|
||||
final short opcode = buffer.readUnsignedByte();
|
||||
switch (opcode) {
|
||||
case LogoutPacket.OPCODE:
|
||||
return LogoutPacket.class;
|
||||
case ProtocolVersionPacket.OPCODE:
|
||||
return ProtocolVersionPacket.class;
|
||||
case AuthLoginPacket.OPCODE:
|
||||
return AuthLoginPacket.class;
|
||||
case CharacterCreatePacket.OPCODE:
|
||||
return CharacterCreatePacket.class;
|
||||
case RequestNewCharacterPacket.OPCODE:
|
||||
return RequestNewCharacterPacket.class;
|
||||
// COMPOSED
|
||||
case 0xd0:
|
||||
final int opcode2 = buffer.readUnsignedShort();
|
||||
switch (opcode2) {
|
||||
case RequestGotoLobby.OPCODE2:
|
||||
return RequestGotoLobby.class;
|
||||
default:
|
||||
logger.warn("Unknown opcode2: 0x{}",
|
||||
Integer.toHexString(opcode));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
logger.info("Unknown opcode: " + Integer.toHexString(opcode));
|
||||
logger.warn("Unknown opcode: 0x{}", Integer.toHexString(opcode));
|
||||
break;
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -21,7 +21,7 @@ public class Lineage2PacketWriter extends OneToOneEncoder {
|
||||
final ServerPacket packet = (ServerPacket) msg;
|
||||
buffer.writeShort(0x0000);
|
||||
buffer.writeByte(packet.getOpcode()); // packet opcode
|
||||
packet.write(buffer);
|
||||
packet.write(buffer);
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,9 +15,9 @@ public class Lineage2PacketHandler extends SimpleChannelHandler {
|
||||
public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e)
|
||||
throws Exception {
|
||||
connection = new Lineage2Connection(e.getChannel());
|
||||
|
||||
|
||||
System.out.println(e);
|
||||
|
||||
|
||||
super.channelOpen(ctx, e);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
package com.l2jserver.game.net.packet;
|
||||
|
||||
|
||||
public abstract class AbstractClientPacket implements ClientPacket {
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
package com.l2jserver.game.net.packet;
|
||||
|
||||
|
||||
public interface Packet {
|
||||
}
|
||||
|
||||
@@ -4,5 +4,6 @@ import org.jboss.netty.buffer.ChannelBuffer;
|
||||
|
||||
public interface ServerPacket extends Packet {
|
||||
void write(ChannelBuffer buffer);
|
||||
|
||||
int getOpcode();
|
||||
}
|
||||
|
||||
@@ -1,23 +1,29 @@
|
||||
package com.l2jserver.game.net.packet.client;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.jboss.netty.buffer.ChannelBuffer;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.l2jserver.db.dao.CharacterDAO;
|
||||
import com.l2jserver.game.net.Lineage2Connection;
|
||||
import com.l2jserver.game.net.Lineage2Session;
|
||||
import com.l2jserver.game.net.packet.AbstractClientPacket;
|
||||
import com.l2jserver.game.net.packet.server.CharSelectionInfoPacket;
|
||||
import com.l2jserver.model.id.object.factory.CharacterIDFactory;
|
||||
import com.l2jserver.game.net.packet.server.CharacterSelectionListPacket;
|
||||
import com.l2jserver.model.world.L2Character;
|
||||
import com.l2jserver.service.game.world.WorldService;
|
||||
import com.l2jserver.util.BufferUtil;
|
||||
|
||||
/**
|
||||
* This packet is sent by the client once the login server has authorized
|
||||
* authentication into this server. A new {@link Lineage2Session} object will be
|
||||
* set to the current connection and the character list is sent to the client.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class AuthLoginPacket extends AbstractClientPacket {
|
||||
public static final int OPCODE = 0x2b;
|
||||
|
||||
@Inject
|
||||
private WorldService world;
|
||||
@Inject
|
||||
private CharacterIDFactory idFactory;
|
||||
private final CharacterDAO characterDao;
|
||||
|
||||
// packet
|
||||
private String loginName;
|
||||
@@ -26,6 +32,11 @@ public class AuthLoginPacket extends AbstractClientPacket {
|
||||
private int loginKey1;
|
||||
private int loginKey2;
|
||||
|
||||
@Inject
|
||||
public AuthLoginPacket(CharacterDAO characterDao) {
|
||||
this.characterDao = characterDao;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(ChannelBuffer buffer) {
|
||||
this.loginName = BufferUtil.readString(buffer);
|
||||
@@ -38,11 +49,13 @@ public class AuthLoginPacket extends AbstractClientPacket {
|
||||
|
||||
@Override
|
||||
public void process(final Lineage2Connection conn) {
|
||||
// assume it is correct, for now
|
||||
// send character list
|
||||
// world.getEventDispatcher().dispatch(null);
|
||||
final L2Character c = idFactory.createID(268435456).getObject();
|
||||
conn.write(new CharSelectionInfoPacket(loginName, playKey1, -1, c));
|
||||
conn.setSession(new Lineage2Session(loginName, playKey1, playKey2,
|
||||
loginKey1, loginKey2));
|
||||
|
||||
final List<L2Character> chars = characterDao.selectByAccount(conn
|
||||
.getSession().getUsername());
|
||||
conn.write(CharacterSelectionListPacket.fromL2Session(
|
||||
conn.getSession(), chars.toArray(new L2Character[0])));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,164 @@
|
||||
package com.l2jserver.game.net.packet.client;
|
||||
|
||||
import org.jboss.netty.buffer.ChannelBuffer;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.l2jserver.db.dao.CharacterDAO;
|
||||
import com.l2jserver.game.net.Lineage2Connection;
|
||||
import com.l2jserver.game.net.packet.AbstractClientPacket;
|
||||
import com.l2jserver.game.net.packet.server.CharacterCreateFailPacket;
|
||||
import com.l2jserver.game.net.packet.server.CharacterCreateOkPacket;
|
||||
import com.l2jserver.model.id.object.CharacterID;
|
||||
import com.l2jserver.model.id.object.factory.CharacterIDFactory;
|
||||
import com.l2jserver.model.id.template.CharacterTemplateID;
|
||||
import com.l2jserver.model.id.template.factory.CharacterTemplateIDFactory;
|
||||
import com.l2jserver.model.template.CharacterTemplate;
|
||||
import com.l2jserver.model.world.AbstractActor.Race;
|
||||
import com.l2jserver.model.world.AbstractActor.Sex;
|
||||
import com.l2jserver.model.world.L2Character;
|
||||
import com.l2jserver.model.world.character.CharacterAppearance.CharacterFace;
|
||||
import com.l2jserver.model.world.character.CharacterAppearance.CharacterHairColor;
|
||||
import com.l2jserver.model.world.character.CharacterAppearance.CharacterHairStyle;
|
||||
import com.l2jserver.util.BufferUtil;
|
||||
|
||||
/**
|
||||
* Completes the creation of an character. Creates the object, inserts into the
|
||||
* database and notifies the client abou the status of the operation.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class CharacterCreatePacket extends AbstractClientPacket {
|
||||
public static final int OPCODE = 0x0c;
|
||||
|
||||
/**
|
||||
* The logger
|
||||
*/
|
||||
private static final Logger log = LoggerFactory
|
||||
.getLogger(CharacterCreatePacket.class);
|
||||
|
||||
// services and daos
|
||||
private final CharacterDAO characterDao;
|
||||
private final CharacterIDFactory characterIdFactory;
|
||||
private final CharacterTemplateIDFactory characterTemplateIdFactory;
|
||||
|
||||
// packet
|
||||
private String name;
|
||||
private Race race;
|
||||
private Sex sex;
|
||||
private int classId;
|
||||
|
||||
private int intelligence;
|
||||
private int strength;
|
||||
private int concentration;
|
||||
private int mentality;
|
||||
private int dextry;
|
||||
private int witness;
|
||||
|
||||
private CharacterHairStyle hairStyle;
|
||||
private CharacterHairColor hairColor;
|
||||
private CharacterFace face;
|
||||
|
||||
@Inject
|
||||
public CharacterCreatePacket(CharacterDAO characterDao,
|
||||
CharacterIDFactory characterIdFactory,
|
||||
CharacterTemplateIDFactory characterTemplateIdFactory) {
|
||||
this.characterDao = characterDao;
|
||||
this.characterIdFactory = characterIdFactory;
|
||||
this.characterTemplateIdFactory = characterTemplateIdFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(ChannelBuffer buffer) {
|
||||
name = BufferUtil.readString(buffer);
|
||||
race = Race.fromOption(buffer.readInt());
|
||||
sex = Sex.fromOption(buffer.readInt());
|
||||
classId = buffer.readInt();
|
||||
|
||||
intelligence = buffer.readInt();
|
||||
strength = buffer.readInt();
|
||||
concentration = buffer.readInt();
|
||||
mentality = buffer.readInt();
|
||||
dextry = buffer.readInt();
|
||||
witness = buffer.readInt();
|
||||
|
||||
hairStyle = CharacterHairStyle.fromOption(buffer.readInt());
|
||||
hairColor = CharacterHairColor.fromOption(buffer.readInt());
|
||||
face = CharacterFace.fromOption(buffer.readInt());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void process(final Lineage2Connection conn) {
|
||||
log.debug("Creating a new character");
|
||||
if ((name.length() < 1) || (name.length() > 16)) {
|
||||
log.debug("Character name length invalid: {}. Aborting.", name);
|
||||
conn.write(new CharacterCreateFailPacket(
|
||||
CharacterCreateFailPacket.Reason.REASON_16_ENG_CHARS));
|
||||
return;
|
||||
}
|
||||
// TODO check alphanumeric name
|
||||
if (sex == null || hairStyle == null || hairColor == null
|
||||
|| face == null) {
|
||||
log.debug("Character appearance invalid. Aborting.");
|
||||
// if some of those attributes is null, something wrong happened.
|
||||
// Maybe we don't support the value sent!
|
||||
conn.write(new CharacterCreateFailPacket(
|
||||
CharacterCreateFailPacket.Reason.REASON_CREATION_FAILED));
|
||||
return;
|
||||
}
|
||||
// existence check
|
||||
final L2Character existenceCheck = characterDao.selectByName(name);
|
||||
if (existenceCheck != null) {
|
||||
log.debug("Character name already exists: {}. Aborting.", name);
|
||||
conn.write(new CharacterCreateFailPacket(
|
||||
CharacterCreateFailPacket.Reason.REASON_NAME_ALREADY_EXISTS));
|
||||
return;
|
||||
}
|
||||
|
||||
// create template id and lookup for the template instance
|
||||
final CharacterTemplateID templateId = characterTemplateIdFactory
|
||||
.createID(classId);
|
||||
final CharacterTemplate template = templateId.getTemplate();
|
||||
log.debug("Creating character with template {}", template);
|
||||
|
||||
// ensure parameters passed by the client are true
|
||||
if ((intelligence != template.getIntelligence())
|
||||
|| (strength != template.getStrength())
|
||||
|| (concentration != template.getConcentration())
|
||||
|| (mentality != template.getMentality())
|
||||
|| (dextry != template.getDextry())
|
||||
|| (witness != template.getWitness())
|
||||
|| (race != template.getRace())) {
|
||||
log.debug(
|
||||
"Values sent by client and sent from template does not match: {}",
|
||||
template);
|
||||
// some of the values didn't match, canceling creation
|
||||
conn.write(new CharacterCreateFailPacket(
|
||||
CharacterCreateFailPacket.Reason.REASON_CREATION_FAILED));
|
||||
return;
|
||||
}
|
||||
|
||||
// everything is fine, allocate a new ID
|
||||
final CharacterID id = characterIdFactory.createID();
|
||||
// create the instance from the template
|
||||
final L2Character character = template.create();
|
||||
|
||||
log.debug("Character object created, ID: {}, Object: {}", id, character);
|
||||
|
||||
// set parameters
|
||||
character.setID(id);
|
||||
character.setName(name);
|
||||
|
||||
character.setSex(sex);
|
||||
|
||||
character.getAppearance().setHairStyle(hairStyle);
|
||||
character.getAppearance().setHairColor(hairColor);
|
||||
character.getAppearance().setFace(face);
|
||||
|
||||
if (characterDao.save(character)) {
|
||||
log.debug("Character saved to database");
|
||||
conn.write(CharacterCreateOkPacket.INSTANCE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.l2jserver.game.net.packet.client;
|
||||
|
||||
import org.jboss.netty.buffer.ChannelBuffer;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.l2jserver.game.net.Lineage2Connection;
|
||||
import com.l2jserver.game.net.packet.AbstractClientPacket;
|
||||
|
||||
/**
|
||||
* The client is requesting a logout. Currently, when this packet is received
|
||||
* the connection is immediately closed.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class LogoutPacket extends AbstractClientPacket {
|
||||
public static final int OPCODE = 0x00;
|
||||
|
||||
/**
|
||||
* The logger
|
||||
*/
|
||||
private static final Logger log = LoggerFactory
|
||||
.getLogger(LogoutPacket.class);
|
||||
|
||||
@Override
|
||||
public void read(ChannelBuffer buffer) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void process(final Lineage2Connection conn) {
|
||||
log.debug("Logging out client {}", conn);
|
||||
conn.close();
|
||||
}
|
||||
}
|
||||
@@ -11,11 +11,21 @@ import com.l2jserver.game.net.Lineage2Connection;
|
||||
import com.l2jserver.game.net.packet.AbstractClientPacket;
|
||||
import com.l2jserver.game.net.packet.server.KeyPacket;
|
||||
|
||||
/**
|
||||
* In this packet the client is informing its protocol version. It is possible
|
||||
* to do an test and refuse invalid protocol versions. After this packet, the
|
||||
* messages received and sent are all encrypted, except for the encryptation key
|
||||
* which is sent here.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class ProtocolVersionPacket extends AbstractClientPacket {
|
||||
public static final int OPCODE = 0x0e;
|
||||
|
||||
// services
|
||||
private final Logger logger = LoggerFactory
|
||||
/**
|
||||
* The logger
|
||||
*/
|
||||
private final Logger log = LoggerFactory
|
||||
.getLogger(ProtocolVersionPacket.class);
|
||||
|
||||
// packet
|
||||
@@ -30,9 +40,11 @@ public class ProtocolVersionPacket extends AbstractClientPacket {
|
||||
public void process(final Lineage2Connection conn) {
|
||||
// generate a new key
|
||||
final byte[] key = conn.getDecrypter().enable();
|
||||
|
||||
log.debug("Decrypter has been enabled");
|
||||
|
||||
log.debug("Client protocol version: {}", version);
|
||||
if (L2JConstants.SUPPORTED_PROTOCOL != version) {
|
||||
logger.info(
|
||||
log.info(
|
||||
"Incorrect protocol version: {0}. Only {1} is supported.",
|
||||
version, L2JConstants.SUPPORTED_PROTOCOL);
|
||||
// notify wrong protocol and close connection
|
||||
@@ -53,6 +65,7 @@ public class ProtocolVersionPacket extends AbstractClientPacket {
|
||||
@Override
|
||||
public void operationComplete(ChannelFuture future)
|
||||
throws Exception {
|
||||
log.debug("Encrypter has been enabled");
|
||||
// enable encrypter
|
||||
conn.getEncrypter().setKey(key);
|
||||
conn.getEncrypter().setEnabled(true);
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.l2jserver.game.net.packet.client;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.jboss.netty.buffer.ChannelBuffer;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.l2jserver.db.dao.CharacterDAO;
|
||||
import com.l2jserver.game.net.Lineage2Connection;
|
||||
import com.l2jserver.game.net.packet.AbstractClientPacket;
|
||||
import com.l2jserver.game.net.packet.server.CharacterSelectionListPacket;
|
||||
import com.l2jserver.model.world.L2Character;
|
||||
|
||||
/**
|
||||
* Requests the list of characters to be displayed in the lobby. The list of
|
||||
* characters is sent to the client.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class RequestGotoLobby extends AbstractClientPacket {
|
||||
public static final int OPCODE1 = 0xd0;
|
||||
public static final int OPCODE2 = 0x36;
|
||||
|
||||
private final CharacterDAO characterDao;
|
||||
|
||||
@Inject
|
||||
public RequestGotoLobby(CharacterDAO characterDao) {
|
||||
this.characterDao = characterDao;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(ChannelBuffer buffer) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void process(final Lineage2Connection conn) {
|
||||
final List<L2Character> chars = characterDao.selectByAccount(conn
|
||||
.getSession().getUsername());
|
||||
conn.write(CharacterSelectionListPacket.fromL2Session(
|
||||
conn.getSession(), chars.toArray(new L2Character[0])));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package com.l2jserver.game.net.packet.client;
|
||||
|
||||
import org.jboss.netty.buffer.ChannelBuffer;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.l2jserver.game.net.Lineage2Connection;
|
||||
import com.l2jserver.game.net.packet.AbstractClientPacket;
|
||||
import com.l2jserver.game.net.packet.server.CharacterTemplatePacket;
|
||||
import com.l2jserver.model.id.template.CharacterTemplateID;
|
||||
import com.l2jserver.model.id.template.factory.CharacterTemplateIDFactory;
|
||||
import com.l2jserver.model.template.CharacterTemplate;
|
||||
|
||||
/**
|
||||
* Requests the creation of a new Character. The list of character templates is
|
||||
* sent to the client, meaning that the client is autorized to create
|
||||
* characters.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class RequestNewCharacterPacket extends AbstractClientPacket {
|
||||
public static final int OPCODE = 0x13;
|
||||
|
||||
/**
|
||||
* The logger
|
||||
*/
|
||||
private static final Logger log = LoggerFactory
|
||||
.getLogger(RequestNewCharacterPacket.class);
|
||||
|
||||
private final CharacterTemplateIDFactory idFactory;
|
||||
|
||||
@Inject
|
||||
public RequestNewCharacterPacket(CharacterTemplateIDFactory idFactory) {
|
||||
this.idFactory = idFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(ChannelBuffer buffer) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void process(final Lineage2Connection conn) {
|
||||
log.debug("Requested character templates");
|
||||
final CharacterTemplateID id = idFactory
|
||||
.createID(Integer.MAX_VALUE - 1);
|
||||
final CharacterTemplate template = id.getTemplate();
|
||||
|
||||
final CharacterTemplatePacket templatePacket = new CharacterTemplatePacket(
|
||||
template);
|
||||
conn.write(templatePacket);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package com.l2jserver.game.net.packet.server;
|
||||
|
||||
import org.jboss.netty.buffer.ChannelBuffer;
|
||||
|
||||
import com.l2jserver.game.net.packet.AbstractServerPacket;
|
||||
|
||||
/**
|
||||
* An packet informing that the character could not be created.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
* @see Reason
|
||||
*/
|
||||
public class CharacterCreateFailPacket extends AbstractServerPacket {
|
||||
public static final int OPCODE = 0x10;
|
||||
|
||||
private Reason reason;
|
||||
|
||||
/**
|
||||
* The character creation error reason
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public enum Reason {
|
||||
/**
|
||||
* "Your character creation has failed."
|
||||
*/
|
||||
REASON_CREATION_FAILED(0x00),
|
||||
/**
|
||||
* "You cannot create another character. Please delete the existing
|
||||
* character and try again." Removes all settings that were selected
|
||||
* (race, class, etc)"
|
||||
*/
|
||||
REASON_TOO_MANY_CHARACTERS(0x01),
|
||||
/**
|
||||
* "This name already exists."
|
||||
*/
|
||||
REASON_NAME_ALREADY_EXISTS(0x02),
|
||||
/**
|
||||
* "Your title cannot exceed 16 characters in length. Please try again."
|
||||
*/
|
||||
REASON_16_ENG_CHARS(0x03),
|
||||
/**
|
||||
* "Incorrect name. Please try again."
|
||||
*/
|
||||
REASON_INCORRECT_NAME(0x04),
|
||||
/**
|
||||
* "Characters cannot be created from this server."
|
||||
*/
|
||||
REASON_CREATE_NOT_ALLOWED(0x05),
|
||||
/**
|
||||
* "Unable to create character. You are unable to create a new character
|
||||
* on the selected server. A restriction is in place which restricts
|
||||
* users from creating characters on different servers where no previous
|
||||
* character exists. Please choose another server."
|
||||
*/
|
||||
REASON_CHOOSE_ANOTHER_SVR(0x06);
|
||||
|
||||
public final int id;
|
||||
|
||||
private Reason(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
|
||||
public CharacterCreateFailPacket(Reason reason) {
|
||||
super(OPCODE);
|
||||
this.reason = reason;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ChannelBuffer buffer) {
|
||||
buffer.writeInt(reason.id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.l2jserver.game.net.packet.server;
|
||||
|
||||
import org.jboss.netty.buffer.ChannelBuffer;
|
||||
|
||||
import com.l2jserver.game.net.packet.AbstractServerPacket;
|
||||
|
||||
/**
|
||||
* An packet informing that the character was created with success.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class CharacterCreateOkPacket extends AbstractServerPacket {
|
||||
public static final int OPCODE = 0x0f;
|
||||
|
||||
public static final CharacterCreateOkPacket INSTANCE = new CharacterCreateOkPacket();
|
||||
|
||||
public CharacterCreateOkPacket() {
|
||||
super(OPCODE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ChannelBuffer buffer) {
|
||||
buffer.writeInt(0x01);
|
||||
}
|
||||
}
|
||||
@@ -2,11 +2,17 @@ package com.l2jserver.game.net.packet.server;
|
||||
|
||||
import org.jboss.netty.buffer.ChannelBuffer;
|
||||
|
||||
import com.l2jserver.game.net.Lineage2Session;
|
||||
import com.l2jserver.game.net.packet.AbstractServerPacket;
|
||||
import com.l2jserver.model.world.L2Character;
|
||||
import com.l2jserver.util.BufferUtil;
|
||||
|
||||
public class CharSelectionInfoPacket extends AbstractServerPacket {
|
||||
/**
|
||||
* The list of characters sent to the client.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class CharacterSelectionListPacket extends AbstractServerPacket {
|
||||
public static final int OPCODE = 0x09;
|
||||
|
||||
private final String loginName;
|
||||
@@ -14,7 +20,7 @@ public class CharSelectionInfoPacket extends AbstractServerPacket {
|
||||
private int lastCharacterId;
|
||||
private final L2Character[] characters;
|
||||
|
||||
public CharSelectionInfoPacket(String loginName, int sessionId,
|
||||
public CharacterSelectionListPacket(String loginName, int sessionId,
|
||||
int lastCharacterId, L2Character... characters) {
|
||||
super(OPCODE);
|
||||
this.loginName = loginName;
|
||||
@@ -23,6 +29,12 @@ public class CharSelectionInfoPacket extends AbstractServerPacket {
|
||||
this.characters = characters;
|
||||
}
|
||||
|
||||
public static CharacterSelectionListPacket fromL2Session(
|
||||
Lineage2Session session, L2Character... characters) {
|
||||
return new CharacterSelectionListPacket(session.getUsername(),
|
||||
session.getPlayKey1(), -1, characters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ChannelBuffer buffer) {
|
||||
// buffer.writeByte(0x09);
|
||||
@@ -30,44 +42,28 @@ public class CharSelectionInfoPacket extends AbstractServerPacket {
|
||||
|
||||
// Can prevent players from creating new characters (if 0); (if 1,
|
||||
// the client will ask if chars may be created (0x13) Response: (0x0D) )
|
||||
buffer.writeInt(0x07);
|
||||
buffer.writeInt(0x01);
|
||||
buffer.writeByte(0x00);
|
||||
|
||||
long lastAccess = 0L;
|
||||
|
||||
if (lastCharacterId == -1) {
|
||||
for (int i = 0; i < characters.length; i++) {
|
||||
if (characters[i].getLastAccess() == null)
|
||||
continue;
|
||||
if (lastAccess < characters[i].getLastAccess().getTime()) {
|
||||
lastAccess = characters[i].getLastAccess().getTime();
|
||||
lastCharacterId = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
for (final L2Character character : characters) {
|
||||
// buffer.writeBytes(character.getName().getBytes());
|
||||
// buffer.writeByte(0x00); // NULL termination
|
||||
BufferUtil.writeString(buffer, character.getName());
|
||||
buffer.writeInt(character.getID().getID());
|
||||
BufferUtil.writeString(buffer, loginName);
|
||||
// buffer.writeBytes(loginName.getBytes());
|
||||
// buffer.writeByte(0x00); // NULL termination
|
||||
buffer.writeInt(sessionId);
|
||||
if (character.getClanID() == null) {
|
||||
buffer.writeInt(0x00); // clan id
|
||||
} else {
|
||||
buffer.writeInt(character.getClanID().getID()); // clan id
|
||||
}
|
||||
// if (character.getClanID() == null) {
|
||||
buffer.writeInt(0x00); // clan id
|
||||
// } else {
|
||||
// buffer.writeInt(character.getClanID().getID()); // clan id
|
||||
// }
|
||||
buffer.writeInt(0x00); // ??
|
||||
|
||||
buffer.writeInt(0x00); // sex
|
||||
buffer.writeInt(0x00); // race
|
||||
buffer.writeInt(character.getSex().option); // sex
|
||||
buffer.writeInt(character.getRace().option); // race
|
||||
|
||||
// if (character.getClassId() == character.getBaseClassId())
|
||||
buffer.writeInt(0x00);
|
||||
buffer.writeInt(character.getCharacterClass().id); // base class id
|
||||
// or class id
|
||||
// else
|
||||
// buffer.writeInt(character.getBaseClassId());
|
||||
|
||||
@@ -81,20 +77,20 @@ public class CharSelectionInfoPacket extends AbstractServerPacket {
|
||||
buffer.writeDouble(20); // mp cur
|
||||
|
||||
buffer.writeInt(3000); // sp
|
||||
buffer.writeLong(0); // exp
|
||||
buffer.writeLong(2000); // exp
|
||||
buffer.writeInt(0x01); // level
|
||||
|
||||
buffer.writeInt(0x00); // karma
|
||||
buffer.writeInt(0x00); // pk
|
||||
|
||||
buffer.writeInt(0x00); // pvp
|
||||
buffer.writeInt(0x00);
|
||||
buffer.writeInt(0x00);
|
||||
buffer.writeInt(0x00);
|
||||
buffer.writeInt(0x00);
|
||||
buffer.writeInt(0x00);
|
||||
buffer.writeInt(0x00);
|
||||
buffer.writeInt(0x00);
|
||||
|
||||
buffer.writeInt(0x00); // unk
|
||||
buffer.writeInt(0x00); // unk
|
||||
buffer.writeInt(0x00); // unk
|
||||
buffer.writeInt(0x00); // unk
|
||||
buffer.writeInt(0x00); // unk
|
||||
buffer.writeInt(0x00); // unk
|
||||
buffer.writeInt(0x00); // unk
|
||||
|
||||
for (int id = 0; id < 26; id++) {
|
||||
buffer.writeInt(0x00); // paperdolls
|
||||
@@ -126,22 +122,19 @@ public class CharSelectionInfoPacket extends AbstractServerPacket {
|
||||
// buffer.writeInt(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_DECO6));
|
||||
// buffer.writeInt(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_BELT));
|
||||
|
||||
buffer.writeInt(0x01); // hair style
|
||||
buffer.writeInt(0x01); // hair color
|
||||
buffer.writeInt(0x01); // face
|
||||
// hair style
|
||||
buffer.writeInt(character.getAppearance().getHairStyle().option);
|
||||
// hair color
|
||||
buffer.writeInt(character.getAppearance().getHairColor().option);
|
||||
// face
|
||||
buffer.writeInt(character.getAppearance().getFace().option);
|
||||
|
||||
buffer.writeDouble(30); // hp max
|
||||
buffer.writeDouble(30); // mp max
|
||||
|
||||
long deleteTime = 0;
|
||||
int deletedays = 0;
|
||||
if (deleteTime > 0)
|
||||
deletedays = (int) ((deleteTime - System.currentTimeMillis()) / 1000);
|
||||
buffer.writeInt(deletedays); // days left before
|
||||
// delete .. if != 0
|
||||
// then char is inactive
|
||||
buffer.writeInt(0x00); // class
|
||||
buffer.writeInt(0x01); // c3 auto-select char
|
||||
buffer.writeInt(0x0); // seconds left before delete
|
||||
buffer.writeInt(character.getCharacterClass().id); // class
|
||||
buffer.writeInt(0x00); // c3 auto-select char
|
||||
|
||||
buffer.writeByte(0x00); // enchant effect
|
||||
|
||||
@@ -153,8 +146,8 @@ public class CharSelectionInfoPacket extends AbstractServerPacket {
|
||||
// character select you don't see your transformation.
|
||||
|
||||
// Freya by Vistall:
|
||||
buffer.writeInt(0); // npdid - 16024 Tame Tiny Baby Kookaburra
|
||||
// A9E89C
|
||||
// buffer.writeInt(0); // npdid - 16024 Tame Tiny Baby Kookaburra
|
||||
// // A9E89C
|
||||
buffer.writeInt(0); // level
|
||||
buffer.writeInt(0); // ?
|
||||
buffer.writeInt(0); // food? - 1200
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.l2jserver.game.net.packet.server;
|
||||
|
||||
import org.jboss.netty.buffer.ChannelBuffer;
|
||||
|
||||
import com.l2jserver.game.net.packet.AbstractServerPacket;
|
||||
import com.l2jserver.model.template.CharacterTemplate;
|
||||
|
||||
/**
|
||||
* An packet that sends all character templates to the client.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class CharacterTemplatePacket extends AbstractServerPacket {
|
||||
public static final int OPCODE = 0x0d;
|
||||
|
||||
private CharacterTemplate[] templates;
|
||||
|
||||
public CharacterTemplatePacket(CharacterTemplate... templates) {
|
||||
super(OPCODE);
|
||||
this.templates = templates;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ChannelBuffer buffer) {
|
||||
buffer.writeInt(templates.length);
|
||||
for (final CharacterTemplate template : templates) {
|
||||
buffer.writeInt(template.getRace().option);
|
||||
buffer.writeInt(template.getCharacterClass().id);
|
||||
buffer.writeInt(0x46);
|
||||
buffer.writeInt(template.getBaseAttributes().getStrength());
|
||||
buffer.writeInt(0x0a);
|
||||
buffer.writeInt(0x46);
|
||||
buffer.writeInt(template.getBaseAttributes().getDextry());
|
||||
buffer.writeInt(0x0a);
|
||||
buffer.writeInt(0x46);
|
||||
buffer.writeInt(template.getBaseAttributes().getConcentration());
|
||||
buffer.writeInt(0x0a);
|
||||
buffer.writeInt(0x46);
|
||||
buffer.writeInt(template.getBaseAttributes().getIntelligence());
|
||||
buffer.writeInt(0x0a);
|
||||
buffer.writeInt(0x46);
|
||||
buffer.writeInt(template.getBaseAttributes().getWitness());
|
||||
buffer.writeInt(0x0a);
|
||||
buffer.writeInt(0x46);
|
||||
buffer.writeInt(template.getBaseAttributes().getMentality());
|
||||
buffer.writeInt(0x0a);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,10 +7,8 @@ import org.jboss.netty.buffer.ChannelBuffer;
|
||||
import com.l2jserver.game.net.packet.AbstractServerPacket;
|
||||
|
||||
/**
|
||||
* <h1>0x2e "KeyPacket"</h1>
|
||||
* <p>
|
||||
* byte[8] key<br>
|
||||
* byte protocolStatus
|
||||
* This packet send the encryptation keys for the client. After this message all
|
||||
* communication is done with the cryptography engine enabled.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
package com.l2jserver.model.id;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.l2jserver.model.template.Template;
|
||||
import com.l2jserver.model.world.WorldObject;
|
||||
|
||||
/**
|
||||
* The ID interface. Each Object or Template must be represented by an unique
|
||||
* ID.
|
||||
* The ID interface. Each {@link WorldObject} or {@link Template} must be
|
||||
* represented by an unique ID.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
@@ -35,7 +37,7 @@ public abstract class ID {
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + id;
|
||||
result = prime * result + id + this.getClass().hashCode();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ package com.l2jserver.model.id;
|
||||
|
||||
import com.l2jserver.model.template.Template;
|
||||
|
||||
|
||||
/**
|
||||
* Templates IDs, different from {@link ObjectID}s, can be repeated and are
|
||||
* defined in the template class.
|
||||
@@ -14,6 +13,6 @@ public abstract class TemplateID<T extends Template> extends ID {
|
||||
public TemplateID(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
|
||||
public abstract T getTemplate();
|
||||
}
|
||||
|
||||
@@ -15,5 +15,5 @@ public interface IDFactory<T extends ID> {
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
T createID(int id);
|
||||
T createID(int id);
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import com.l2jserver.model.id.object.factory.CharacterIDFactory;
|
||||
import com.l2jserver.model.id.object.factory.CharacterIDFactory.CharacterIDGuiceFactory;
|
||||
import com.l2jserver.model.id.object.factory.ItemIDFactory;
|
||||
import com.l2jserver.model.id.object.factory.ItemIDFactory.ItemIDGuiceFactory;
|
||||
import com.l2jserver.model.id.template.factory.CharacterTemplateIDFactory;
|
||||
import com.l2jserver.model.id.template.factory.ItemTemplateIDFactory;
|
||||
import com.l2jserver.model.id.template.factory.SkillTemplateIDFactory;
|
||||
|
||||
@@ -34,5 +35,7 @@ public class IDFactoryModule extends AbstractModule {
|
||||
// TEMPLATE IDS
|
||||
install(new FactoryModuleBuilder().build(ItemTemplateIDFactory.class));
|
||||
install(new FactoryModuleBuilder().build(SkillTemplateIDFactory.class));
|
||||
install(new FactoryModuleBuilder()
|
||||
.build(CharacterTemplateIDFactory.class));
|
||||
}
|
||||
}
|
||||
|
||||
13
src/main/java/com/l2jserver/model/id/object/ActorID.java
Normal file
13
src/main/java/com/l2jserver/model/id/object/ActorID.java
Normal file
@@ -0,0 +1,13 @@
|
||||
package com.l2jserver.model.id.object;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
import com.l2jserver.model.id.ObjectID;
|
||||
import com.l2jserver.model.world.capability.Actor;
|
||||
|
||||
public abstract class ActorID<T extends Actor> extends ObjectID<T> {
|
||||
@Inject
|
||||
public ActorID(@Assisted int id) {
|
||||
super(id);
|
||||
}
|
||||
}
|
||||
@@ -3,10 +3,9 @@ package com.l2jserver.model.id.object;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
import com.l2jserver.db.dao.CharacterDAO;
|
||||
import com.l2jserver.model.id.ObjectID;
|
||||
import com.l2jserver.model.world.L2Character;
|
||||
|
||||
public final class CharacterID extends ObjectID<L2Character> {
|
||||
public final class CharacterID extends ActorID<L2Character> {
|
||||
/**
|
||||
* Data Access Object (DAO) for characters
|
||||
*/
|
||||
|
||||
@@ -2,10 +2,9 @@ package com.l2jserver.model.id.object;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.l2jserver.db.dao.PetDAO;
|
||||
import com.l2jserver.model.id.ObjectID;
|
||||
import com.l2jserver.model.world.Pet;
|
||||
|
||||
public final class PetID extends ObjectID<Pet> {
|
||||
public final class PetID extends ActorID<Pet> {
|
||||
/**
|
||||
* Data Access Object (DAO) for pets
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.l2jserver.model.id.template;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
import com.l2jserver.model.id.TemplateID;
|
||||
import com.l2jserver.model.template.CharacterTemplate;
|
||||
import com.l2jserver.service.game.template.TemplateService;
|
||||
|
||||
public class CharacterTemplateID extends TemplateID<CharacterTemplate> {
|
||||
private final TemplateService templateService;
|
||||
|
||||
@Inject
|
||||
protected CharacterTemplateID(@Assisted int id,
|
||||
TemplateService templateService) {
|
||||
super(id);
|
||||
this.templateService = templateService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharacterTemplate getTemplate() {
|
||||
return (CharacterTemplate) templateService.getTemplate(this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.l2jserver.model.id.template.factory;
|
||||
|
||||
import com.l2jserver.model.id.template.CharacterTemplateID;
|
||||
|
||||
public interface CharacterTemplateIDFactory extends
|
||||
TemplateIDFactory<CharacterTemplateID> {
|
||||
}
|
||||
@@ -2,7 +2,7 @@ package com.l2jserver.model.template;
|
||||
|
||||
import com.l2jserver.model.id.TemplateID;
|
||||
|
||||
public class AbstractTemplate implements Template {
|
||||
public abstract class AbstractTemplate<T> implements Template<T> {
|
||||
private final TemplateID<?> id;
|
||||
|
||||
public AbstractTemplate(TemplateID<?> id) {
|
||||
|
||||
@@ -0,0 +1,250 @@
|
||||
package com.l2jserver.model.template;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.l2jserver.model.id.template.CharacterTemplateID;
|
||||
import com.l2jserver.model.world.AbstractActor.Race;
|
||||
import com.l2jserver.model.world.L2Character;
|
||||
import com.l2jserver.model.world.character.CharacterBaseAttributes;
|
||||
import com.l2jserver.model.world.character.CharacterClass;
|
||||
import com.l2jserver.util.Coordinate;
|
||||
|
||||
public abstract class CharacterTemplate extends AbstractTemplate<L2Character> {
|
||||
/**
|
||||
* The logger
|
||||
*/
|
||||
private static final Logger log = LoggerFactory
|
||||
.getLogger(CharacterTemplate.class);
|
||||
|
||||
/**
|
||||
* The character race
|
||||
*/
|
||||
protected final Race race;
|
||||
/**
|
||||
* The character class
|
||||
*/
|
||||
protected final CharacterClass characterClass;
|
||||
/**
|
||||
* The initial location for the character to be spawned
|
||||
*/
|
||||
protected final Coordinate spawnLocation;
|
||||
/**
|
||||
* The base attributes instance
|
||||
*/
|
||||
protected final CharacterBaseAttributes baseAttributes;
|
||||
|
||||
public CharacterTemplate(CharacterTemplateID id,
|
||||
CharacterClass characterClass, int intelligence, int strength,
|
||||
int concentration, int mentality, int dextry, int witness,
|
||||
int physicalAttack, int magicalAttack, int physicalDefense,
|
||||
int magicalDefense, int attackSpeed, int castSpeed, int accuracy,
|
||||
int criticalChance, int evasionChance, int moveSpeed,
|
||||
int maxWeigth, boolean craft, Coordinate spawnLocation) {
|
||||
super(id);
|
||||
this.race = characterClass.race;
|
||||
this.characterClass = characterClass;
|
||||
this.spawnLocation = spawnLocation;
|
||||
baseAttributes = new CharacterBaseAttributes(intelligence, strength,
|
||||
concentration, mentality, dextry, witness, physicalAttack,
|
||||
magicalAttack, physicalDefense, magicalDefense, attackSpeed,
|
||||
castSpeed, accuracy, criticalChance, evasionChance, moveSpeed,
|
||||
maxWeigth, craft);
|
||||
}
|
||||
|
||||
@Override
|
||||
public L2Character create() {
|
||||
log.debug("Creating a new Character instance with template {}", this);
|
||||
final L2Character character = new L2Character(baseAttributes);
|
||||
|
||||
character.setRace(race);
|
||||
character.setCharacterClass(characterClass);
|
||||
character.setPosition(spawnLocation);
|
||||
|
||||
// character.getBaseAttributes().setIntelligence(intelligence);
|
||||
// character.getBaseAttributes().setStrength(strength);
|
||||
// character.getBaseAttributes().setConcentration(concentration);
|
||||
// character.getBaseAttributes().setMentality(mentality);
|
||||
// character.getBaseAttributes().setDextry(dextry);
|
||||
// character.getBaseAttributes().setWitness(witness);
|
||||
|
||||
return character;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the race
|
||||
*/
|
||||
public Race getRace() {
|
||||
return race;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the characterClass
|
||||
*/
|
||||
public CharacterClass getCharacterClass() {
|
||||
return characterClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the spawnLocation
|
||||
*/
|
||||
public Coordinate getSpawnLocation() {
|
||||
return spawnLocation;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the baseAttributes
|
||||
*/
|
||||
public CharacterBaseAttributes getBaseAttributes() {
|
||||
return baseAttributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
* @see com.l2jserver.model.world.character.CharacterBaseAttributes#getIntelligence()
|
||||
*/
|
||||
public int getIntelligence() {
|
||||
return baseAttributes.getIntelligence();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
* @see com.l2jserver.model.world.character.CharacterBaseAttributes#getStrength()
|
||||
*/
|
||||
public int getStrength() {
|
||||
return baseAttributes.getStrength();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
* @see com.l2jserver.model.world.character.CharacterBaseAttributes#getConcentration()
|
||||
*/
|
||||
public int getConcentration() {
|
||||
return baseAttributes.getConcentration();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
* @see com.l2jserver.model.world.character.CharacterBaseAttributes#getMentality()
|
||||
*/
|
||||
public int getMentality() {
|
||||
return baseAttributes.getMentality();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
* @see com.l2jserver.model.world.character.CharacterBaseAttributes#getDextry()
|
||||
*/
|
||||
public int getDextry() {
|
||||
return baseAttributes.getDextry();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
* @see com.l2jserver.model.world.character.CharacterBaseAttributes#getWitness()
|
||||
*/
|
||||
public int getWitness() {
|
||||
return baseAttributes.getWitness();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
* @see com.l2jserver.model.world.character.CharacterBaseAttributes#getPhysicalAttack()
|
||||
*/
|
||||
public int getPhysicalAttack() {
|
||||
return baseAttributes.getPhysicalAttack();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
* @see com.l2jserver.model.world.character.CharacterBaseAttributes#getMagicalAttack()
|
||||
*/
|
||||
public int getMagicalAttack() {
|
||||
return baseAttributes.getMagicalAttack();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
* @see com.l2jserver.model.world.character.CharacterBaseAttributes#getPhysicalDefense()
|
||||
*/
|
||||
public int getPhysicalDefense() {
|
||||
return baseAttributes.getPhysicalDefense();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
* @see com.l2jserver.model.world.character.CharacterBaseAttributes#getMagicalDefense()
|
||||
*/
|
||||
public int getMagicalDefense() {
|
||||
return baseAttributes.getMagicalDefense();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
* @see com.l2jserver.model.world.character.CharacterBaseAttributes#getAttackSpeed()
|
||||
*/
|
||||
public int getAttackSpeed() {
|
||||
return baseAttributes.getAttackSpeed();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
* @see com.l2jserver.model.world.character.CharacterBaseAttributes#getCastSpeed()
|
||||
*/
|
||||
public int getCastSpeed() {
|
||||
return baseAttributes.getCastSpeed();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
* @see com.l2jserver.model.world.character.CharacterBaseAttributes#getAccuracy()
|
||||
*/
|
||||
public int getAccuracy() {
|
||||
return baseAttributes.getAccuracy();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
* @see com.l2jserver.model.world.character.CharacterBaseAttributes#getCriticalChance()
|
||||
*/
|
||||
public int getCriticalChance() {
|
||||
return baseAttributes.getCriticalChance();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
* @see com.l2jserver.model.world.character.CharacterBaseAttributes#getEvasionChance()
|
||||
*/
|
||||
public int getEvasionChance() {
|
||||
return baseAttributes.getEvasionChance();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
* @see com.l2jserver.model.world.character.CharacterBaseAttributes#getMoveSpeed()
|
||||
*/
|
||||
public int getMoveSpeed() {
|
||||
return baseAttributes.getMoveSpeed();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
* @see com.l2jserver.model.world.character.CharacterBaseAttributes#getMaxWeigth()
|
||||
*/
|
||||
public int getMaxWeigth() {
|
||||
return baseAttributes.getMaxWeigth();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
* @see com.l2jserver.model.world.character.CharacterBaseAttributes#canCraft()
|
||||
*/
|
||||
public boolean canCraft() {
|
||||
return baseAttributes.canCraft();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharacterTemplateID getID() {
|
||||
return (CharacterTemplateID) super.getID();
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,28 @@
|
||||
package com.l2jserver.model.template;
|
||||
|
||||
import com.l2jserver.model.id.template.ItemTemplateID;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.l2jserver.model.id.template.ItemTemplateID;
|
||||
import com.l2jserver.model.world.Item;
|
||||
|
||||
public abstract class ItemTemplate extends AbstractTemplate<Item> {
|
||||
/**
|
||||
* The logger
|
||||
*/
|
||||
private static final Logger log = LoggerFactory
|
||||
.getLogger(ItemTemplate.class);
|
||||
|
||||
public abstract class ItemTemplate extends AbstractTemplate {
|
||||
public ItemTemplate(ItemTemplateID id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Item create() {
|
||||
log.debug("Creating a new Item instance with template {}", this);
|
||||
return new Item(this.getID());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemTemplateID getID() {
|
||||
return (ItemTemplateID) super.getID();
|
||||
|
||||
@@ -2,13 +2,21 @@ package com.l2jserver.model.template;
|
||||
|
||||
import com.l2jserver.model.id.template.SkillTemplateID;
|
||||
import com.l2jserver.model.template.capability.Castable;
|
||||
import com.l2jserver.model.world.character.CharacterClass;
|
||||
|
||||
public abstract class SkillTemplate extends AbstractTemplate implements
|
||||
public abstract class SkillTemplate extends AbstractTemplate<Void> implements
|
||||
Castable {
|
||||
public SkillTemplate(SkillTemplateID id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public abstract CharacterClass[] getClasses();
|
||||
|
||||
@Override
|
||||
public Void create() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SkillTemplateID getID() {
|
||||
return (SkillTemplateID) super.getID();
|
||||
|
||||
@@ -2,6 +2,8 @@ package com.l2jserver.model.template;
|
||||
|
||||
import com.l2jserver.model.id.TemplateID;
|
||||
|
||||
public interface Template {
|
||||
public interface Template<T> {
|
||||
T create();
|
||||
|
||||
TemplateID<?> getID();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.l2jserver.model.template.capability;
|
||||
|
||||
|
||||
public interface Enchantable extends TemplateCapability {
|
||||
void enchant(com.l2jserver.model.world.capability.Enchantable target);
|
||||
}
|
||||
|
||||
@@ -1,26 +1,74 @@
|
||||
package com.l2jserver.model.world;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.l2jserver.model.template.SkillTemplate;
|
||||
import com.l2jserver.model.template.capability.Attackable;
|
||||
import com.l2jserver.model.world.actor.ActorListener;
|
||||
import com.l2jserver.model.world.actor.ActorEffects;
|
||||
import com.l2jserver.model.world.capability.Actor;
|
||||
import com.l2jserver.model.world.capability.Attacker;
|
||||
import com.l2jserver.model.world.capability.Castable;
|
||||
import com.l2jserver.model.world.capability.Equipable;
|
||||
import com.l2jserver.model.world.capability.Equiper;
|
||||
import com.l2jserver.util.Coordinate;
|
||||
import com.l2jserver.util.factory.CollectionFactory;
|
||||
|
||||
public abstract class AbstractActor extends AbstractObject implements Actor {
|
||||
private final List<ActorListener> listeners = CollectionFactory
|
||||
.newList(ActorListener.class);
|
||||
protected Race race;
|
||||
|
||||
/**
|
||||
* Represents the actor race.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public enum Race {
|
||||
HUMAN(0x00), ELF(0x01), DARK_ELF(0x02), ORC(0x03), DWARF(0x04), KAMAEL(
|
||||
0x05);
|
||||
|
||||
public final int option;
|
||||
|
||||
Race(int option) {
|
||||
this.option = option;
|
||||
}
|
||||
|
||||
public static Race fromOption(int option) {
|
||||
for (final Race race : values()) {
|
||||
if (race.option == option)
|
||||
return race;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected Sex sex;
|
||||
|
||||
/**
|
||||
* Represent the sex of an actor.
|
||||
* <p>
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public enum Sex {
|
||||
MALE(0x00), FEMALE(0x01);
|
||||
|
||||
public final int option;
|
||||
|
||||
Sex(int option) {
|
||||
this.option = option;
|
||||
}
|
||||
|
||||
public static Sex fromOption(int option) {
|
||||
for (Sex sex : values()) {
|
||||
if (sex.option == option)
|
||||
return sex;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected int level;
|
||||
protected int hp;
|
||||
protected Coordinate position;
|
||||
|
||||
protected final ActorEffects effects = new ActorEffects(this);
|
||||
|
||||
@Override
|
||||
public void receiveDamage(int damage) {
|
||||
// TODO Auto-generated method stub
|
||||
@@ -78,6 +126,36 @@ public abstract class AbstractActor extends AbstractObject implements Actor {
|
||||
this.position = coord;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the race
|
||||
*/
|
||||
public Race getRace() {
|
||||
return race;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param race
|
||||
* the race to set
|
||||
*/
|
||||
public void setRace(Race race) {
|
||||
this.race = race;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the sex
|
||||
*/
|
||||
public Sex getSex() {
|
||||
return sex;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param sex
|
||||
* the sex to set
|
||||
*/
|
||||
public void setSex(Sex sex) {
|
||||
this.sex = sex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLevel() {
|
||||
return level;
|
||||
@@ -88,6 +166,13 @@ public abstract class AbstractActor extends AbstractObject implements Actor {
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the active effects on this actor
|
||||
*/
|
||||
public ActorEffects getEffects() {
|
||||
return effects;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void die(WorldObject killer) {
|
||||
// TODO
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
package com.l2jserver.model.world;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.l2jserver.model.id.object.CharacterID;
|
||||
import com.l2jserver.model.id.template.ItemTemplateID;
|
||||
import com.l2jserver.model.world.capability.Listenable;
|
||||
import com.l2jserver.model.world.capability.Playable;
|
||||
import com.l2jserver.model.world.capability.Spawnable;
|
||||
import com.l2jserver.model.world.item.ItemEvent;
|
||||
import com.l2jserver.model.world.item.ItemListener;
|
||||
import com.l2jserver.util.Coordinate;
|
||||
import com.l2jserver.util.factory.CollectionFactory;
|
||||
|
||||
public class Item extends AbstractObject implements Playable, Spawnable,
|
||||
Listenable<ItemListener, ItemEvent> {
|
||||
private final List<ItemListener> listeners = CollectionFactory
|
||||
.newList(ItemListener.class);
|
||||
|
||||
private final ItemTemplateID templateID;
|
||||
private CharacterID ownerID;
|
||||
|
||||
public Item(ItemTemplateID templateID) {
|
||||
this.templateID = templateID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void spawn(Coordinate coordinate) {
|
||||
|
||||
@@ -39,7 +39,14 @@ public class Item extends AbstractObject implements Playable, Spawnable,
|
||||
public void setPosition(Coordinate coord) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the templateID
|
||||
*/
|
||||
public ItemTemplateID getTemplateID() {
|
||||
return templateID;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the ownerID
|
||||
*/
|
||||
|
||||
@@ -6,6 +6,10 @@ import com.l2jserver.model.id.object.CharacterID;
|
||||
import com.l2jserver.model.id.object.ClanID;
|
||||
import com.l2jserver.model.id.object.PetID;
|
||||
import com.l2jserver.model.world.character.CharacterAppearance;
|
||||
import com.l2jserver.model.world.character.CharacterAttributes;
|
||||
import com.l2jserver.model.world.character.CharacterBaseAttributes;
|
||||
import com.l2jserver.model.world.character.CharacterCalculatedAttributes;
|
||||
import com.l2jserver.model.world.character.CharacterClass;
|
||||
import com.l2jserver.model.world.character.CharacterInventory;
|
||||
|
||||
/**
|
||||
@@ -26,6 +30,10 @@ public class L2Character extends Player {
|
||||
* The character name
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* The class of the character
|
||||
*/
|
||||
private CharacterClass characterClass;
|
||||
/**
|
||||
* The character's status
|
||||
*/
|
||||
@@ -43,6 +51,25 @@ public class L2Character extends Player {
|
||||
* The appearance of this character
|
||||
*/
|
||||
private final CharacterAppearance appearance = new CharacterAppearance(this);
|
||||
/**
|
||||
* The base attributes of this character
|
||||
*/
|
||||
private final CharacterBaseAttributes baseAttributes;
|
||||
/**
|
||||
* The attributes of this character
|
||||
*/
|
||||
private final CharacterAttributes attributes;
|
||||
|
||||
/**
|
||||
* Creates a new instance
|
||||
*
|
||||
* @param baseAttributes
|
||||
* the base attribute for this character
|
||||
*/
|
||||
public L2Character(CharacterBaseAttributes baseAttributes) {
|
||||
this.baseAttributes = baseAttributes;
|
||||
this.attributes = new CharacterCalculatedAttributes(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharacterID getID() {
|
||||
@@ -112,6 +139,21 @@ public class L2Character extends Player {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the characterClass
|
||||
*/
|
||||
public CharacterClass getCharacterClass() {
|
||||
return characterClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param characterClass
|
||||
* the characterClass to set
|
||||
*/
|
||||
public void setCharacterClass(CharacterClass characterClass) {
|
||||
this.characterClass = characterClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the online
|
||||
*/
|
||||
@@ -155,4 +197,18 @@ public class L2Character extends Player {
|
||||
public CharacterAppearance getAppearance() {
|
||||
return appearance;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the base attributes
|
||||
*/
|
||||
public CharacterBaseAttributes getBaseAttributes() {
|
||||
return baseAttributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the attributes
|
||||
*/
|
||||
public CharacterAttributes getAttributes() {
|
||||
return attributes;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,9 +12,6 @@ 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);
|
||||
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.l2jserver.model.world.actor;
|
||||
|
||||
import com.l2jserver.model.world.capability.Actor;
|
||||
|
||||
public class ActorEffects {
|
||||
private final Actor actor;
|
||||
|
||||
public ActorEffects(Actor actor) {
|
||||
this.actor = actor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the actor
|
||||
*/
|
||||
public Actor getActor() {
|
||||
return actor;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.l2jserver.model.world.capability;
|
||||
|
||||
import com.l2jserver.model.world.AbstractObject;
|
||||
import com.l2jserver.model.world.actor.ActorEffects;
|
||||
import com.l2jserver.model.world.actor.ActorEvent;
|
||||
import com.l2jserver.model.world.actor.ActorListener;
|
||||
|
||||
@@ -13,5 +14,5 @@ import com.l2jserver.model.world.actor.ActorListener;
|
||||
public interface Actor extends Listenable<ActorListener, ActorEvent>,
|
||||
Spawnable, Positionable, Damagable, Attackable, Attacker, Castable,
|
||||
Caster, Levelable, Killable, Equiper, Equipable {
|
||||
|
||||
ActorEffects getEffects();
|
||||
}
|
||||
|
||||
@@ -10,9 +10,11 @@ import com.l2jserver.model.world.AbstractObject;
|
||||
*/
|
||||
public interface Equiper extends ObjectCapability {
|
||||
void equip(Equipable equipable);
|
||||
|
||||
|
||||
boolean isEquiped(Equipable equipment);
|
||||
boolean isEquiped(com.l2jserver.model.template.capability.Equipable equipable);
|
||||
|
||||
boolean isEquiped(
|
||||
com.l2jserver.model.template.capability.Equipable equipable);
|
||||
|
||||
void setEquipment(Object slot, Equipable equipment);
|
||||
|
||||
|
||||
@@ -10,5 +10,6 @@ import com.l2jserver.util.Coordinate;
|
||||
*/
|
||||
public interface Positionable extends ObjectCapability {
|
||||
Coordinate getPosition();
|
||||
|
||||
void setPosition(Coordinate coord);
|
||||
}
|
||||
|
||||
@@ -25,21 +25,19 @@ public class CharacterAppearance {
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public enum CharacterFace {
|
||||
FACE1((byte) 0x00),
|
||||
FACE_A(0x00),
|
||||
|
||||
FACE2((byte) 0x01),
|
||||
FACE_B(0x01),
|
||||
|
||||
FACE3((byte) 0x02),
|
||||
FACE_C(0x02);
|
||||
|
||||
FACE4((byte) 0x03);
|
||||
public final int option;
|
||||
|
||||
public final byte option;
|
||||
|
||||
CharacterFace(byte option) {
|
||||
CharacterFace(int option) {
|
||||
this.option = option;
|
||||
}
|
||||
|
||||
public static CharacterFace fromOption(byte option) {
|
||||
public static CharacterFace fromOption(int option) {
|
||||
for (CharacterFace face : values()) {
|
||||
if (face.option == option)
|
||||
return face;
|
||||
@@ -59,21 +57,21 @@ public class CharacterAppearance {
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public enum CharacterHairColor {
|
||||
COLOR1((byte) 0x00),
|
||||
COLOR_A(0x00),
|
||||
|
||||
COLOR2((byte) 0x01),
|
||||
COLOR_B(0x01),
|
||||
|
||||
COLOR3((byte) 0x02),
|
||||
COLOR_C(0x02),
|
||||
|
||||
COLOR4((byte) 0x03);
|
||||
COLOR_D(0x03);
|
||||
|
||||
public final byte option;
|
||||
public final int option;
|
||||
|
||||
CharacterHairColor(byte option) {
|
||||
CharacterHairColor(int option) {
|
||||
this.option = option;
|
||||
}
|
||||
|
||||
public static CharacterHairColor fromOption(byte option) {
|
||||
public static CharacterHairColor fromOption(int option) {
|
||||
for (CharacterHairColor color : values()) {
|
||||
if (color.option == option)
|
||||
return color;
|
||||
@@ -93,21 +91,23 @@ public class CharacterAppearance {
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public enum CharacterHairStyle {
|
||||
STYLE1((byte) 0x00),
|
||||
STYLE_A(0x00),
|
||||
|
||||
STYLE2((byte) 0x01),
|
||||
STYLE_B(0x01),
|
||||
|
||||
STYLE3((byte) 0x02),
|
||||
STYLE_C(0x02),
|
||||
|
||||
STYLE4((byte) 0x03);
|
||||
STYLE_D(0x03),
|
||||
|
||||
public final byte option;
|
||||
STYLE_E(0x04);
|
||||
|
||||
CharacterHairStyle(byte option) {
|
||||
public final int option;
|
||||
|
||||
CharacterHairStyle(int option) {
|
||||
this.option = option;
|
||||
}
|
||||
|
||||
public static CharacterHairStyle fromOption(byte option) {
|
||||
public static CharacterHairStyle fromOption(int option) {
|
||||
for (CharacterHairStyle style : values()) {
|
||||
if (style.option == option)
|
||||
return style;
|
||||
@@ -116,23 +116,6 @@ public class CharacterAppearance {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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>
|
||||
@@ -148,14 +131,16 @@ public class CharacterAppearance {
|
||||
|
||||
/**
|
||||
* The name color
|
||||
* <p>
|
||||
* <b>This is not persisted!</b>
|
||||
*/
|
||||
private RGBColor nameColor = new RGBColor((byte) 0xFF, (byte) 0xFF,
|
||||
(byte) 0xFF);
|
||||
private RGBColor nameColor = RGBColor.fromInteger(0xFFFFFF);
|
||||
/**
|
||||
* The title color
|
||||
* <p>
|
||||
* <b>This is not persisted!</b>
|
||||
*/
|
||||
private RGBColor titleColor = new RGBColor((byte) 0xFF, (byte) 0xFF,
|
||||
(byte) 0x77);
|
||||
private RGBColor titleColor = RGBColor.fromInteger(0xFFFF77);
|
||||
|
||||
public CharacterAppearance(L2Character character) {
|
||||
this.character = character;
|
||||
@@ -206,21 +191,6 @@ public class CharacterAppearance {
|
||||
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
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
package com.l2jserver.model.world.character;
|
||||
|
||||
public interface CharacterAttributes {
|
||||
/**
|
||||
* @return the intelligence
|
||||
*/
|
||||
public int getIntelligence();
|
||||
|
||||
/**
|
||||
* @return the strength
|
||||
*/
|
||||
public int getStrength();
|
||||
|
||||
/**
|
||||
* @return the concentration
|
||||
*/
|
||||
public int getConcentration();
|
||||
|
||||
/**
|
||||
* @return the mentality
|
||||
*/
|
||||
public int getMentality();
|
||||
|
||||
/**
|
||||
* @return the dextry
|
||||
*/
|
||||
public int getDextry();
|
||||
|
||||
/**
|
||||
* @return the witness
|
||||
*/
|
||||
public int getWitness();
|
||||
|
||||
/**
|
||||
* @return the physicalAttack
|
||||
*/
|
||||
public int getPhysicalAttack();
|
||||
|
||||
/**
|
||||
* @return the magicalAttack
|
||||
*/
|
||||
public int getMagicalAttack();
|
||||
|
||||
/**
|
||||
* @return the physicalDefense
|
||||
*/
|
||||
public int getPhysicalDefense();
|
||||
|
||||
/**
|
||||
* @return the magicalDefense
|
||||
*/
|
||||
public int getMagicalDefense();
|
||||
|
||||
/**
|
||||
* @return the attackSpeed
|
||||
*/
|
||||
public int getAttackSpeed();
|
||||
|
||||
/**
|
||||
* @return the castSpeed
|
||||
*/
|
||||
public int getCastSpeed();
|
||||
|
||||
/**
|
||||
* @return the accuracy
|
||||
*/
|
||||
public int getAccuracy();
|
||||
|
||||
/**
|
||||
* @return the criticalChance
|
||||
*/
|
||||
public int getCriticalChance();
|
||||
|
||||
/**
|
||||
* @return the evasionChance
|
||||
*/
|
||||
public int getEvasionChance();
|
||||
|
||||
/**
|
||||
* @return the movement speed
|
||||
*/
|
||||
public int getMoveSpeed();
|
||||
|
||||
/**
|
||||
* @return the maxWeigth
|
||||
*/
|
||||
public int getMaxWeigth();
|
||||
|
||||
/**
|
||||
* @return the craft
|
||||
*/
|
||||
public boolean canCraft();
|
||||
}
|
||||
@@ -0,0 +1,276 @@
|
||||
package com.l2jserver.model.world.character;
|
||||
|
||||
/**
|
||||
* Defines the attributes of an character
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class CharacterBaseAttributes implements CharacterAttributes {
|
||||
/**
|
||||
* The character intelligence
|
||||
*/
|
||||
private final int intelligence;
|
||||
/**
|
||||
* The character strength
|
||||
*/
|
||||
private final int strength;
|
||||
/**
|
||||
* The character concentration
|
||||
*/
|
||||
private final int concentration;
|
||||
/**
|
||||
* The character mentality power
|
||||
*/
|
||||
private final int mentality;
|
||||
/**
|
||||
* The character dextry
|
||||
*/
|
||||
private final int dextry;
|
||||
/**
|
||||
* The character witness
|
||||
*/
|
||||
private final int witness;
|
||||
|
||||
/**
|
||||
* The default physical attack
|
||||
*/
|
||||
private final int physicalAttack;
|
||||
/**
|
||||
* The default magical attack
|
||||
*/
|
||||
private final int magicalAttack;
|
||||
/**
|
||||
* The physical defense
|
||||
*/
|
||||
private final int physicalDefense;
|
||||
/**
|
||||
* The magical defense
|
||||
*/
|
||||
private final int magicalDefense;
|
||||
|
||||
/**
|
||||
* The physical attack speed
|
||||
*/
|
||||
private final int attackSpeed;
|
||||
/**
|
||||
* The "magical attack speed" (aka cast speed)
|
||||
*/
|
||||
private final int castSpeed;
|
||||
|
||||
/**
|
||||
* The character accuracy
|
||||
*/
|
||||
private final int accuracy;
|
||||
/**
|
||||
* Chance of issuing an critical attack
|
||||
*/
|
||||
private final int criticalChance;
|
||||
/**
|
||||
* Chance of avoiding an attack
|
||||
*/
|
||||
private final int evasionChance;
|
||||
/**
|
||||
* The character's movement speed
|
||||
*/
|
||||
private final int moveSpeed;
|
||||
/**
|
||||
* The maximum weigth in items to be carried in the inventory
|
||||
*/
|
||||
private final int maxWeigth;
|
||||
/**
|
||||
* If this character can craft
|
||||
*/
|
||||
private final boolean craft;
|
||||
|
||||
/**
|
||||
* Creates a new instance
|
||||
*
|
||||
* @param intelligence
|
||||
* the intelligence
|
||||
* @param strength
|
||||
* the strength
|
||||
* @param concentration
|
||||
* the concentration
|
||||
* @param mentality
|
||||
* the mentality
|
||||
* @param dextry
|
||||
* the dextry
|
||||
* @param witness
|
||||
* the witness
|
||||
* @param physicalAttack
|
||||
* the physical attack
|
||||
* @param magicalAttack
|
||||
* the magical attack
|
||||
* @param physicalDefense
|
||||
* the physical defense
|
||||
* @param magicalDefense
|
||||
* the magical defense
|
||||
* @param attackSpeed
|
||||
* the attack speed
|
||||
* @param castSpeed
|
||||
* the cast speed
|
||||
* @param accuracy
|
||||
* the accuracy
|
||||
* @param criticalChance
|
||||
* the critical chance
|
||||
* @param evasionChance
|
||||
* the evasion chance
|
||||
* @param maxWeigth
|
||||
* the maximum weight in inventory
|
||||
* @param moveSpeed
|
||||
* the character movement speed
|
||||
* @param craft
|
||||
* if the character can craft items
|
||||
*/
|
||||
public CharacterBaseAttributes(int intelligence, int strength,
|
||||
int concentration, int mentality, int dextry, int witness,
|
||||
int physicalAttack, int magicalAttack, int physicalDefense,
|
||||
int magicalDefense, int attackSpeed, int castSpeed, int accuracy,
|
||||
int criticalChance, int evasionChance, int moveSpeed,
|
||||
int maxWeigth, boolean craft) {
|
||||
this.intelligence = intelligence;
|
||||
this.strength = strength;
|
||||
this.concentration = concentration;
|
||||
this.mentality = mentality;
|
||||
this.dextry = dextry;
|
||||
this.witness = witness;
|
||||
this.physicalAttack = physicalAttack;
|
||||
this.magicalAttack = magicalAttack;
|
||||
this.physicalDefense = physicalDefense;
|
||||
this.magicalDefense = magicalDefense;
|
||||
this.attackSpeed = attackSpeed;
|
||||
this.castSpeed = castSpeed;
|
||||
this.accuracy = accuracy;
|
||||
this.criticalChance = criticalChance;
|
||||
this.evasionChance = evasionChance;
|
||||
this.moveSpeed = moveSpeed;
|
||||
this.maxWeigth = maxWeigth;
|
||||
this.craft = craft;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the intelligence
|
||||
*/
|
||||
public int getIntelligence() {
|
||||
return intelligence;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the strength
|
||||
*/
|
||||
public int getStrength() {
|
||||
return strength;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the concentration
|
||||
*/
|
||||
public int getConcentration() {
|
||||
return concentration;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the mentality
|
||||
*/
|
||||
public int getMentality() {
|
||||
return mentality;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the dextry
|
||||
*/
|
||||
public int getDextry() {
|
||||
return dextry;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the witness
|
||||
*/
|
||||
public int getWitness() {
|
||||
return witness;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the physicalAttack
|
||||
*/
|
||||
public int getPhysicalAttack() {
|
||||
return physicalAttack;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the magicalAttack
|
||||
*/
|
||||
public int getMagicalAttack() {
|
||||
return magicalAttack;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the physicalDefense
|
||||
*/
|
||||
public int getPhysicalDefense() {
|
||||
return physicalDefense;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the magicalDefense
|
||||
*/
|
||||
public int getMagicalDefense() {
|
||||
return magicalDefense;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the attackSpeed
|
||||
*/
|
||||
public int getAttackSpeed() {
|
||||
return attackSpeed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the castSpeed
|
||||
*/
|
||||
public int getCastSpeed() {
|
||||
return castSpeed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the accuracy
|
||||
*/
|
||||
public int getAccuracy() {
|
||||
return accuracy;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the criticalChance
|
||||
*/
|
||||
public int getCriticalChance() {
|
||||
return criticalChance;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the evasionChance
|
||||
*/
|
||||
public int getEvasionChance() {
|
||||
return evasionChance;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the moveSpeed
|
||||
*/
|
||||
public int getMoveSpeed() {
|
||||
return moveSpeed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the maxWeigth
|
||||
*/
|
||||
public int getMaxWeigth() {
|
||||
return maxWeigth;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the craft
|
||||
*/
|
||||
public boolean canCraft() {
|
||||
return craft;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
package com.l2jserver.model.world.character;
|
||||
|
||||
import com.l2jserver.model.world.L2Character;
|
||||
|
||||
public class CharacterCalculatedAttributes implements CharacterAttributes {
|
||||
private final L2Character character;
|
||||
private final CharacterAttributes baseAttributes;
|
||||
|
||||
public CharacterCalculatedAttributes(L2Character character) {
|
||||
this.character = character;
|
||||
this.baseAttributes = this.character.getBaseAttributes();
|
||||
}
|
||||
|
||||
public int getIntelligence() {
|
||||
return baseAttributes.getIntelligence();
|
||||
}
|
||||
|
||||
public int getStrength() {
|
||||
return baseAttributes.getStrength();
|
||||
}
|
||||
|
||||
public int getConcentration() {
|
||||
return baseAttributes.getConcentration();
|
||||
}
|
||||
|
||||
public int getMentality() {
|
||||
return baseAttributes.getMentality();
|
||||
}
|
||||
|
||||
public int getDextry() {
|
||||
return baseAttributes.getDextry();
|
||||
}
|
||||
|
||||
public int getWitness() {
|
||||
return baseAttributes.getWitness();
|
||||
}
|
||||
|
||||
public int getPhysicalAttack() {
|
||||
return baseAttributes.getPhysicalAttack();
|
||||
}
|
||||
|
||||
public int getMagicalAttack() {
|
||||
return baseAttributes.getMagicalAttack();
|
||||
}
|
||||
|
||||
public int getPhysicalDefense() {
|
||||
return baseAttributes.getPhysicalDefense();
|
||||
}
|
||||
|
||||
public int getMagicalDefense() {
|
||||
return baseAttributes.getMagicalDefense();
|
||||
}
|
||||
|
||||
public int getAttackSpeed() {
|
||||
return baseAttributes.getAttackSpeed();
|
||||
}
|
||||
|
||||
public int getCastSpeed() {
|
||||
return baseAttributes.getCastSpeed();
|
||||
}
|
||||
|
||||
public int getAccuracy() {
|
||||
return baseAttributes.getAccuracy();
|
||||
}
|
||||
|
||||
public int getCriticalChance() {
|
||||
return baseAttributes.getCriticalChance();
|
||||
}
|
||||
|
||||
public int getEvasionChance() {
|
||||
return baseAttributes.getEvasionChance();
|
||||
}
|
||||
|
||||
public int getMoveSpeed() {
|
||||
return baseAttributes.getMoveSpeed();
|
||||
}
|
||||
|
||||
public int getMaxWeigth() {
|
||||
return baseAttributes.getMaxWeigth();
|
||||
}
|
||||
|
||||
public boolean canCraft() {
|
||||
return baseAttributes.canCraft();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
package com.l2jserver.model.world.character;
|
||||
|
||||
import com.l2jserver.model.world.AbstractActor.Race;
|
||||
|
||||
/**
|
||||
* Defines all the possible classes for an character
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public enum CharacterClass {
|
||||
/**
|
||||
* Human fighter
|
||||
*/
|
||||
HUMAN_FIGHTER(0x00, Race.HUMAN), WARRIOR(0x01, HUMAN_FIGHTER), GLADIATOR(
|
||||
0x02, WARRIOR), WARLORD(0x03, WARRIOR), KNIGHT(0x04, HUMAN_FIGHTER), PALADIN(
|
||||
0x05, KNIGHT), DARK_AVENGER(0x06, KNIGHT), ROGUE(0x07,
|
||||
HUMAN_FIGHTER), REASURE_HUNTER(0x08, ROGUE), HAWKEYE(0x09, ROGUE),
|
||||
/**
|
||||
* Human mystic
|
||||
*/
|
||||
HUMAN_MYSTIC(0x0a, true, Race.HUMAN), WIZARD(0x0b, HUMAN_MYSTIC), SORCEROR(
|
||||
0x0c, WIZARD), NECROMANCER(0x0d, WIZARD), WARLOCK(0x0e, true, true,
|
||||
WIZARD), CLERIC(0x0f, HUMAN_MYSTIC), BISHOP(0x10, CLERIC), PROPHET(
|
||||
0x11, CLERIC),
|
||||
|
||||
/**
|
||||
* Elven fighter
|
||||
*/
|
||||
ELVEN_FIGHTER(0x12, Race.ELF), ELVEN_KNIGHT(0x13, ELVEN_FIGHTER), TEMPLE_KNIGHT(
|
||||
0x14, ELVEN_KNIGHT), SWORD_SINGER(0x15, ELVEN_KNIGHT), ELVEN_SCOUT(
|
||||
0x16, ELVEN_FIGHTER), PLAINS_WALKER(0x17, ELVEN_SCOUT), SILVER_RANGER(
|
||||
0x18, ELVEN_SCOUT),
|
||||
/**
|
||||
* Elven mystic
|
||||
*/
|
||||
ELVEN_MYSTIC(0x19, true, Race.ELF), ELVEN_WIZARD(0x1a, ELVEN_MYSTIC), SPELLSINGER(
|
||||
0x1b, ELVEN_WIZARD), ELEMENTAL_SUMMONER(0x1c, true, true,
|
||||
ELVEN_WIZARD), ORACLE(0x1d, ELVEN_MYSTIC), ELDER(0x1e, ORACLE),
|
||||
|
||||
/**
|
||||
* Dark elf fighter
|
||||
*/
|
||||
DARK_FIGHTER(0x1f, Race.DARK_ELF), PALUS_KNIGHT(0x20, DARK_FIGHTER), SHILLIEN_KNIGHT(
|
||||
0x21, PALUS_KNIGHT), BLADEDANCER(0x22, PALUS_KNIGHT), ASSASSIN(
|
||||
0x23, DARK_FIGHTER), ABYSS_WALKER(0x24, ASSASSIN), PHANTOM_RANGER(
|
||||
0x25, ASSASSIN),
|
||||
|
||||
/**
|
||||
* Dark elf mystic
|
||||
*/
|
||||
DARK_MYSTIC(0x26, true, Race.DARK_ELF), DARK_WIZARD(0x27, DARK_MYSTIC), SPELLHOWLER(
|
||||
0x28, DARK_WIZARD), PHANTOM_SUMMONER(0x29, true, true, DARK_WIZARD), SHILLIEN_ORACLE(
|
||||
0x2a, DARK_MYSTIC), SHILLIEN_ELDER(0x2b, SHILLIEN_ORACLE);
|
||||
|
||||
// TODO dwarf classes
|
||||
// TODO kamael classes
|
||||
// TODO 3rd classes
|
||||
|
||||
public final int id;
|
||||
public final boolean mystic;
|
||||
public final boolean summoner;
|
||||
public final Race race;
|
||||
public final CharacterClass parent;
|
||||
|
||||
private CharacterClass(int id, boolean mystic, boolean summoner, Race race,
|
||||
CharacterClass parent) {
|
||||
this.id = id;
|
||||
this.mystic = mystic;
|
||||
this.summoner = summoner;
|
||||
this.race = race;
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
private CharacterClass(int id, CharacterClass parent) {
|
||||
this(id, parent.mystic, parent.summoner, parent.race, parent);
|
||||
}
|
||||
|
||||
private CharacterClass(int id, Race race, CharacterClass parent) {
|
||||
this(id, false, false, race, parent);
|
||||
}
|
||||
|
||||
private CharacterClass(int id, Race race) {
|
||||
this(id, false, false, race, null);
|
||||
}
|
||||
|
||||
private CharacterClass(int id, boolean mystic, Race race) {
|
||||
this(id, mystic, false, race, null);
|
||||
}
|
||||
|
||||
private CharacterClass(int id, boolean mystic, boolean summoner,
|
||||
CharacterClass parent) {
|
||||
this(id, mystic, summoner, parent.race, parent);
|
||||
}
|
||||
|
||||
public CharacterClass fromID(int id) {
|
||||
for (final CharacterClass c : values()) {
|
||||
if (c.id == id)
|
||||
return c;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the level of the class. Base class is zero.
|
||||
*
|
||||
* @return the class level
|
||||
*/
|
||||
public final int level() {
|
||||
if (parent == null)
|
||||
return 0;
|
||||
return 1 + parent.level();
|
||||
}
|
||||
}
|
||||
@@ -5,5 +5,6 @@ import com.l2jserver.util.Coordinate;
|
||||
|
||||
public interface SpawnEvent extends WorldEvent {
|
||||
Spawnable getObject();
|
||||
|
||||
Coordinate getCoordinate();
|
||||
}
|
||||
@@ -11,8 +11,8 @@ public class AndFilter<O extends WorldObject> implements WorldObjectFilter<O> {
|
||||
|
||||
@Override
|
||||
public boolean accept(O object) {
|
||||
for(final WorldObjectFilter<O> filter : filters) {
|
||||
if(!filter.accept(object))
|
||||
for (final WorldObjectFilter<O> filter : filters) {
|
||||
if (!filter.accept(object))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -11,8 +11,8 @@ public class OrFilter<O extends WorldObject> implements WorldObjectFilter<O> {
|
||||
|
||||
@Override
|
||||
public boolean accept(O object) {
|
||||
for(final WorldObjectFilter<O> filter : filters) {
|
||||
if(filter.accept(object))
|
||||
for (final WorldObjectFilter<O> filter : filters) {
|
||||
if (filter.accept(object))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -3,7 +3,8 @@ package com.l2jserver.model.world.filter.impl;
|
||||
import com.l2jserver.model.world.WorldObject;
|
||||
import com.l2jserver.model.world.filter.WorldObjectFilter;
|
||||
|
||||
public class InstanceFilter<T extends WorldObject> implements WorldObjectFilter<T> {
|
||||
public class InstanceFilter<T extends WorldObject> implements
|
||||
WorldObjectFilter<T> {
|
||||
private final Class<?> type;
|
||||
|
||||
public InstanceFilter(Class<?> instance) {
|
||||
|
||||
@@ -4,7 +4,8 @@ import com.google.inject.Inject;
|
||||
import com.l2jserver.service.ServiceManager;
|
||||
import com.l2jserver.service.configuration.ConfigurationService;
|
||||
import com.l2jserver.service.database.DatabaseService;
|
||||
import com.l2jserver.service.logging.LoggingService;
|
||||
import com.l2jserver.service.game.scripting.ScriptingService;
|
||||
import com.l2jserver.service.game.template.TemplateService;
|
||||
import com.l2jserver.service.network.NetworkService;
|
||||
|
||||
public class GameServerInitializationRoutine implements Routine<Boolean> {
|
||||
@@ -17,10 +18,13 @@ public class GameServerInitializationRoutine implements Routine<Boolean> {
|
||||
|
||||
@Override
|
||||
public Boolean call() throws Exception {
|
||||
serviceManager.start(LoggingService.class);
|
||||
// serviceManager.start(LoggingService.class);
|
||||
serviceManager.start(ConfigurationService.class);
|
||||
serviceManager.start(DatabaseService.class);
|
||||
|
||||
|
||||
serviceManager.start(ScriptingService.class);
|
||||
serviceManager.start(TemplateService.class);
|
||||
|
||||
serviceManager.start(NetworkService.class);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,10 @@ package com.l2jserver.service;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Scopes;
|
||||
import com.l2jserver.service.game.scripting.ScriptingService;
|
||||
import com.l2jserver.service.game.scripting.ScriptingServiceImpl;
|
||||
import com.l2jserver.service.game.template.StaticTemplateService;
|
||||
import com.l2jserver.service.game.template.TemplateService;
|
||||
import com.l2jserver.service.game.world.WorldEventDispatcher;
|
||||
import com.l2jserver.service.game.world.WorldEventDispatcherImpl;
|
||||
import com.l2jserver.service.game.world.WorldService;
|
||||
@@ -14,6 +18,10 @@ public class ServiceModule extends AbstractModule {
|
||||
protected void configure() {
|
||||
bind(NetworkService.class).to(NettyNetworkService.class).in(
|
||||
Scopes.SINGLETON);
|
||||
bind(ScriptingService.class).to(ScriptingServiceImpl.class).in(
|
||||
Scopes.SINGLETON);
|
||||
bind(TemplateService.class).to(StaticTemplateService.class).in(
|
||||
Scopes.SINGLETON);
|
||||
|
||||
bind(WorldService.class).to(WorldServiceImpl.class)
|
||||
.in(Scopes.SINGLETON);
|
||||
|
||||
@@ -212,7 +212,7 @@ public class ScriptContextImpl implements ScriptContext {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<ScriptContext> getChildScriptContexts() {
|
||||
public synchronized Collection<ScriptContext> getChildScriptContexts() {
|
||||
return childScriptContexts;
|
||||
}
|
||||
|
||||
@@ -220,7 +220,7 @@ public class ScriptContextImpl implements ScriptContext {
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void addChildScriptContext(ScriptContext context) {
|
||||
public synchronized void addChildScriptContext(ScriptContext context) {
|
||||
synchronized (this) {
|
||||
if (childScriptContexts == null) {
|
||||
childScriptContexts = new HashSet<ScriptContext>();
|
||||
|
||||
@@ -19,6 +19,8 @@ package com.l2jserver.service.game.scripting.impl.javacc;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -109,11 +111,20 @@ public class ClassFileManager extends
|
||||
@Override
|
||||
public synchronized ScriptClassLoaderImpl getClassLoader(Location location) {
|
||||
if (loader == null) {
|
||||
if (parentClassLoader != null) {
|
||||
loader = new ScriptClassLoaderImpl(this, parentClassLoader);
|
||||
} else {
|
||||
loader = new ScriptClassLoaderImpl(this);
|
||||
}
|
||||
return AccessController
|
||||
.doPrivileged(new PrivilegedAction<ScriptClassLoaderImpl>() {
|
||||
@Override
|
||||
public ScriptClassLoaderImpl run() {
|
||||
if (parentClassLoader != null) {
|
||||
return new ScriptClassLoaderImpl(
|
||||
ClassFileManager.this,
|
||||
ClassFileManager.this.parentClassLoader);
|
||||
} else {
|
||||
return new ScriptClassLoaderImpl(
|
||||
ClassFileManager.this);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
return loader;
|
||||
}
|
||||
|
||||
@@ -25,8 +25,7 @@ import java.net.URLConnection;
|
||||
|
||||
/**
|
||||
* This class represents URL Connection that is used to "connect" to scripts
|
||||
* binary data that was loaded by specified
|
||||
* {@link ScriptCompilerImpl}.<br>
|
||||
* binary data that was loaded by specified {@link ScriptCompilerImpl}.<br>
|
||||
* <br>
|
||||
* TODO: Implement all methods of {@link URLConnection} to ensure valid
|
||||
* behaviour
|
||||
|
||||
@@ -22,6 +22,7 @@ public class StaticTemplateService extends AbstractService implements
|
||||
|
||||
private ScriptContext context;
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
private Map<TemplateID, Template> templates = CollectionFactory.newMap(
|
||||
TemplateID.class, Template.class);
|
||||
|
||||
@@ -52,18 +53,18 @@ public class StaticTemplateService extends AbstractService implements
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends Template> T getTemplate(TemplateID<T> id) {
|
||||
public <T extends Template<?>> T getTemplate(TemplateID<T> id) {
|
||||
return (T) templates.get(id);
|
||||
}
|
||||
|
||||
public void addTemplate(Class<? extends Template> t) {
|
||||
final Template template = injector.getInstance(t);
|
||||
public void addTemplate(Class<? extends Template<?>> t) {
|
||||
final Template<?> template = injector.getInstance(t);
|
||||
System.out.println(template.getID() + " -> " + template);
|
||||
if (template.getID() != null)
|
||||
templates.put(template.getID(), template);
|
||||
}
|
||||
|
||||
public void removeTemplate(Template t) {
|
||||
public void removeTemplate(Template<?> t) {
|
||||
// TODO templates.remove(t);
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import com.l2jserver.service.configuration.Configuration.ConfigurationName;
|
||||
public interface StaticTemplateServiceConfiguration extends Configuration {
|
||||
@ConfigurationPropertyGetter(name = "template.descriptor", defaultValue = "data/script/template/template.xml")
|
||||
File getTemplateDescriptor();
|
||||
|
||||
@ConfigurationPropertySetter(name = "template.descriptor")
|
||||
void setTemplateDescriptor(File file);
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ public interface TemplateService extends Service {
|
||||
* the template id
|
||||
* @return the template
|
||||
*/
|
||||
<T extends Template> T getTemplate(TemplateID<T> id);
|
||||
<T extends Template<?>> T getTemplate(TemplateID<T> id);
|
||||
|
||||
/**
|
||||
* Reload the template list.
|
||||
|
||||
@@ -4,6 +4,9 @@ import java.util.Queue;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.l2jserver.model.id.ObjectID;
|
||||
import com.l2jserver.model.world.capability.Listenable;
|
||||
import com.l2jserver.model.world.event.WorldEvent;
|
||||
@@ -16,6 +19,9 @@ import com.l2jserver.util.factory.CollectionFactory;
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class WorldEventDispatcherImpl implements WorldEventDispatcher {
|
||||
private static final Logger log = LoggerFactory
|
||||
.getLogger(WorldEventDispatcherImpl.class);
|
||||
|
||||
private final Timer timer = new Timer();
|
||||
|
||||
private Queue<ListenerIDPair> listeners = CollectionFactory
|
||||
@@ -39,10 +45,12 @@ public class WorldEventDispatcherImpl implements WorldEventDispatcher {
|
||||
}
|
||||
|
||||
public void dispatch(WorldEvent event) {
|
||||
log.debug("Queing dispatch for event {}", event);
|
||||
events.add(event);
|
||||
}
|
||||
|
||||
public void doDispatch(WorldEvent event) {
|
||||
log.debug("Dispatching event {}", event);
|
||||
final Listenable<?, ?>[] objects = event.getDispatchableObjects();
|
||||
for (final ListenerIDPair pair : listeners) {
|
||||
for (Listenable<?, ?> obj : objects) {
|
||||
@@ -54,6 +62,9 @@ public class WorldEventDispatcherImpl implements WorldEventDispatcher {
|
||||
if (pair.dispatch(event))
|
||||
continue;
|
||||
} catch (ClassCastException e) {
|
||||
log.debug(
|
||||
"Exception in Listener. This might indicate an implementation issue in {}",
|
||||
pair.listener.getClass());
|
||||
}
|
||||
listeners.remove(pair);
|
||||
}
|
||||
@@ -64,6 +75,7 @@ public class WorldEventDispatcherImpl implements WorldEventDispatcher {
|
||||
@SuppressWarnings("unchecked")
|
||||
public <E extends WorldEvent, L extends WorldListener<E>> void addListener(
|
||||
Listenable<L, E> object, WorldListener<E> listener) {
|
||||
log.debug("Adding new listener {} to {}", listener, object.getID());
|
||||
listeners.add(new ListenerIDPair(object.getID(),
|
||||
(WorldListener<WorldEvent>) listener));
|
||||
}
|
||||
@@ -72,6 +84,7 @@ public class WorldEventDispatcherImpl implements WorldEventDispatcher {
|
||||
@SuppressWarnings("unchecked")
|
||||
public <E extends WorldEvent, L extends WorldListener<E>> void addListener(
|
||||
ObjectID<? extends Listenable<L, E>> id, WorldListener<E> listener) {
|
||||
log.debug("Adding new listener {} to {}", listener, id);
|
||||
listeners.add(new ListenerIDPair(id,
|
||||
(WorldListener<WorldEvent>) listener));
|
||||
}
|
||||
@@ -80,6 +93,7 @@ public class WorldEventDispatcherImpl implements WorldEventDispatcher {
|
||||
@SuppressWarnings("unchecked")
|
||||
public <E extends WorldEvent, L extends WorldListener<E>> void removeListener(
|
||||
Listenable<L, E> object, WorldListener<E> listener) {
|
||||
log.debug("Removing new listener {} from {}", listener, object.getID());
|
||||
listeners.remove(new ListenerIDPair(object.getID(),
|
||||
(WorldListener<WorldEvent>) listener));
|
||||
}
|
||||
@@ -88,6 +102,7 @@ public class WorldEventDispatcherImpl implements WorldEventDispatcher {
|
||||
@SuppressWarnings("unchecked")
|
||||
public <E extends WorldEvent, L extends WorldListener<E>> void removeListener(
|
||||
ObjectID<? extends Listenable<L, E>> id, WorldListener<E> listener) {
|
||||
log.debug("Removing new listener {} from {}", listener, id);
|
||||
listeners.remove(new ListenerIDPair(id,
|
||||
(WorldListener<WorldEvent>) listener));
|
||||
}
|
||||
|
||||
@@ -4,6 +4,9 @@ import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.l2jserver.model.world.WorldObject;
|
||||
import com.l2jserver.model.world.filter.WorldObjectFilter;
|
||||
@@ -15,6 +18,9 @@ import com.l2jserver.service.ServiceStopException;
|
||||
import com.l2jserver.util.factory.CollectionFactory;
|
||||
|
||||
public class WorldServiceImpl extends AbstractService implements WorldService {
|
||||
private static final Logger log = LoggerFactory
|
||||
.getLogger(WorldServiceImpl.class);
|
||||
|
||||
private final Set<WorldObject> objects = CollectionFactory
|
||||
.newSet(WorldObject.class);
|
||||
private final WorldEventDispatcher dispatcher;
|
||||
@@ -31,11 +37,13 @@ public class WorldServiceImpl extends AbstractService implements WorldService {
|
||||
|
||||
@Override
|
||||
public void add(WorldObject object) {
|
||||
log.debug("Adding object {} to world", object);
|
||||
objects.add(object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(WorldObject object) {
|
||||
log.debug("Removing object {} from world", object);
|
||||
objects.remove(object);
|
||||
}
|
||||
|
||||
@@ -51,6 +59,7 @@ public class WorldServiceImpl extends AbstractService implements WorldService {
|
||||
|
||||
@Override
|
||||
public <T extends WorldObject> List<T> list(WorldObjectFilter<T> filter) {
|
||||
log.debug("Listing objects with filter {}", filter);
|
||||
final List<T> list = CollectionFactory.newList(null);
|
||||
for (final T object : this.iterable(filter)) {
|
||||
list.add(object);
|
||||
@@ -60,6 +69,7 @@ public class WorldServiceImpl extends AbstractService implements WorldService {
|
||||
|
||||
@Override
|
||||
public <T extends WorldObject> List<T> list(Class<T> type) {
|
||||
log.debug("Listing of type {}", type);
|
||||
return list(new InstanceFilter<T>(type));
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,8 @@ import com.l2jserver.game.net.Lineage2PipelineFactory;
|
||||
import com.l2jserver.service.AbstractService;
|
||||
import com.l2jserver.service.configuration.ConfigurationService;
|
||||
|
||||
public class NettyNetworkService extends AbstractService implements NetworkService {
|
||||
public class NettyNetworkService extends AbstractService implements
|
||||
NetworkService {
|
||||
private final NetworkConfiguration config;
|
||||
private final Injector injector;
|
||||
private ServerBootstrap server;
|
||||
|
||||
@@ -16,9 +16,10 @@ public class BufferUtil {
|
||||
}
|
||||
|
||||
public static final void writeString(ChannelBuffer buffer, String str) {
|
||||
for (char c : str.toCharArray()) {
|
||||
buffer.writeChar(c);
|
||||
}
|
||||
buffer.writeChar(0x00);
|
||||
if (str != null)
|
||||
for (char c : str.toCharArray()) {
|
||||
buffer.writeChar(c);
|
||||
}
|
||||
buffer.writeChar('\000');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ public class Coordinate {
|
||||
private final int y;
|
||||
private final int z;
|
||||
|
||||
public Coordinate(int x, int y, int z) {
|
||||
protected Coordinate(int x, int y, int z) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
@@ -22,9 +22,13 @@ public class Coordinate {
|
||||
public int getZ() {
|
||||
return z;
|
||||
}
|
||||
|
||||
|
||||
public int getDistance(Coordinate other) {
|
||||
//TODO calculation
|
||||
// TODO calculation
|
||||
return x + y + z;
|
||||
}
|
||||
|
||||
public static Coordinate fromXYZ(int x, int y, int z) {
|
||||
return new Coordinate(x, y, z);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,26 +11,23 @@ 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.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
@@ -39,119 +36,224 @@ 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.
|
||||
|
||||
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.
|
||||
*
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* "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
|
||||
// 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
|
||||
* 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.
|
||||
*
|
||||
* @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) {
|
||||
if (i < 0) {
|
||||
// desired capacity not found, choose next prime greater
|
||||
// than desired capacity
|
||||
i = -i -1; // remember the semantics of binarySearch...
|
||||
i = -i - 1; // remember the semantics of binarySearch...
|
||||
}
|
||||
return PRIME_CAPACITIES[i];
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ public class RGBColor {
|
||||
private final byte green;
|
||||
private final byte blue;
|
||||
|
||||
public RGBColor(byte r, byte g, byte b) {
|
||||
protected RGBColor(byte r, byte g, byte b) {
|
||||
this.red = r;
|
||||
this.green = g;
|
||||
this.blue = b;
|
||||
@@ -35,4 +35,13 @@ public class RGBColor {
|
||||
public byte[] toByteArray() {
|
||||
return new byte[] { red, green, blue };
|
||||
}
|
||||
|
||||
public static RGBColor fromByteArray(byte[] rgb) {
|
||||
return new RGBColor(rgb[0], rgb[1], rgb[2]);
|
||||
}
|
||||
|
||||
public static RGBColor fromInteger(int color) {
|
||||
return new RGBColor((byte) (color << 0), (byte) (color << 8),
|
||||
(byte) (color << 16));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user