1
0
mirror of https://github.com/Rogiel/l2jserver2 synced 2025-12-06 07:32:46 +00:00

Moved packets back to l2jserver2-gameserver-core module

This commit is contained in:
2012-05-03 17:54:04 -03:00
parent df55c684a9
commit 2d80fac50b
172 changed files with 1093 additions and 8892 deletions

View File

@@ -19,6 +19,7 @@ package com.l2jserver.util;
import java.util.Arrays; import java.util.Arrays;
import java.util.Comparator; import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.StringTokenizer;
import com.l2jserver.util.factory.CollectionFactory; import com.l2jserver.util.factory.CollectionFactory;
@@ -74,4 +75,20 @@ public class ArrayUtils {
public final static <T> boolean contains(T[] array, T expected) { public final static <T> boolean contains(T[] array, T expected) {
return Arrays.binarySearch(array, expected) >= 0; return Arrays.binarySearch(array, expected) >= 0;
} }
/**
* @param tokenizer
* the tokenizer
* @return an array of strings with each parameter
*/
public static String[] createArgumentArray(StringTokenizer tokenizer) {
if (!tokenizer.hasMoreTokens())
return new String[0];
final String[] args = new String[tokenizer.countTokens()];
int i = 0;
while (tokenizer.hasMoreTokens()) {
args[i++] = tokenizer.nextToken();
}
return args;
}
} }

View File

@@ -37,6 +37,7 @@ import com.l2jserver.model.template.ItemTemplate;
import com.l2jserver.model.world.Item; import com.l2jserver.model.world.Item;
import com.l2jserver.model.world.L2Character; import com.l2jserver.model.world.L2Character;
import com.l2jserver.service.network.model.Lineage2Client; import com.l2jserver.service.network.model.Lineage2Client;
import com.l2jserver.service.network.model.Lineage2CryptographyKey;
import com.l2jserver.service.network.model.Lineage2Session; import com.l2jserver.service.network.model.Lineage2Session;
import com.l2jserver.service.network.model.ProtocolVersion; import com.l2jserver.service.network.model.ProtocolVersion;
import com.l2jserver.service.network.model.SystemMessage; import com.l2jserver.service.network.model.SystemMessage;
@@ -52,7 +53,7 @@ import com.l2jserver.util.html.markup.HtmlTemplate;
* *
* @author <a href="http://www.rogiel.com">Rogiel</a> * @author <a href="http://www.rogiel.com">Rogiel</a>
*/ */
public class InterludeLineage2Client implements Lineage2Client { public class Lineage2ClientImpl implements Lineage2Client {
/** /**
* The connection channel * The connection channel
*/ */
@@ -77,7 +78,7 @@ public class InterludeLineage2Client implements Lineage2Client {
* @param channel * @param channel
* the channel * the channel
*/ */
public InterludeLineage2Client(Channel channel) { public Lineage2ClientImpl(Channel channel) {
this.channel = channel; this.channel = channel;
} }
@@ -127,6 +128,16 @@ public class InterludeLineage2Client implements Lineage2Client {
this.session = session; this.session = session;
} }
@Override
public void enableDecrypter(Lineage2CryptographyKey key) {
channel.getPipeline().get(Lineage2Decrypter.class).enable(key);
}
@Override
public void enableEncrypter(Lineage2CryptographyKey key) {
channel.getPipeline().get(Lineage2Encrypter.class).enable(key);
}
/** /**
* @return the version * @return the version
*/ */
@@ -157,6 +168,17 @@ public class InterludeLineage2Client implements Lineage2Client {
return this.version.supports(version); return this.version.supports(version);
} }
@Override
public boolean supports(ProtocolVersion from, ProtocolVersion to) {
if (to == this.version)
return true;
if (from == this.version)
return true;
if (to.supports(this.version))
return false;
return true;
}
/** /**
* Get the channel * Get the channel
* *

View File

@@ -26,8 +26,8 @@ import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelHandler; import org.jboss.netty.channel.SimpleChannelHandler;
import com.google.common.base.Throwables; import com.google.common.base.Throwables;
import com.l2jserver.game.net.FreyaLineage2Client; import com.l2jserver.game.net.Lineage2ClientImpl;
import com.l2jserver.service.network.NettyNetworkService; import com.l2jserver.service.network.AbstractNettyNetworkService;
import com.l2jserver.service.network.model.Lineage2Client; import com.l2jserver.service.network.model.Lineage2Client;
import com.l2jserver.service.network.model.packet.ClientPacket; import com.l2jserver.service.network.model.packet.ClientPacket;
import com.l2jserver.util.html.markup.HtmlTemplate; import com.l2jserver.util.html.markup.HtmlTemplate;
@@ -35,15 +35,15 @@ import com.l2jserver.util.html.markup.MarkupTag;
/** /**
* This handler dispatches the {@link ClientPacket#process(Lineage2Client)} * This handler dispatches the {@link ClientPacket#process(Lineage2Client)}
* method and creates a new {@link Lineage2Client} once a new channel is open. * method and creates a new {@link Lineage2ClientImpl} once a new channel is open.
* *
* @author <a href="http://www.rogiel.com">Rogiel</a> * @author <a href="http://www.rogiel.com">Rogiel</a>
*/ */
public class Lineage2PacketHandler extends SimpleChannelHandler { public class Lineage2PacketHandler extends SimpleChannelHandler {
/** /**
* The {@link NettyNetworkService} * The {@link AbstractNettyNetworkService}
*/ */
private final NettyNetworkService nettyNetworkService; private final AbstractNettyNetworkService nettyNetworkService;
/** /**
* The timeout handler is responsible for disconnecting idle clients. * The timeout handler is responsible for disconnecting idle clients.
*/ */
@@ -51,7 +51,7 @@ public class Lineage2PacketHandler extends SimpleChannelHandler {
/** /**
* The Lineage 2 connection * The Lineage 2 connection
*/ */
private FreyaLineage2Client connection; private Lineage2ClientImpl connection;
/** /**
* Creates a new instance of the packet handler * Creates a new instance of the packet handler
@@ -61,7 +61,7 @@ public class Lineage2PacketHandler extends SimpleChannelHandler {
* @param timeoutHandler * @param timeoutHandler
* the timeout handler * the timeout handler
*/ */
public Lineage2PacketHandler(NettyNetworkService nettyNetworkService, public Lineage2PacketHandler(AbstractNettyNetworkService nettyNetworkService,
Lineage2TimeoutHandler timeoutHandler) { Lineage2TimeoutHandler timeoutHandler) {
this.nettyNetworkService = nettyNetworkService; this.nettyNetworkService = nettyNetworkService;
this.timeoutHandler = timeoutHandler; this.timeoutHandler = timeoutHandler;
@@ -70,7 +70,7 @@ public class Lineage2PacketHandler extends SimpleChannelHandler {
@Override @Override
public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e) public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e)
throws Exception { throws Exception {
connection = new FreyaLineage2Client(e.getChannel()); connection = new Lineage2ClientImpl(e.getChannel());
connection.getPacketWriter().setConnection(connection); connection.getPacketWriter().setConnection(connection);
timeoutHandler.setConnection(connection); timeoutHandler.setConnection(connection);

View File

@@ -28,6 +28,8 @@ import com.l2jserver.model.world.NPC;
import com.l2jserver.model.world.npc.NPCController.NPCControllerException; import com.l2jserver.model.world.npc.NPCController.NPCControllerException;
import com.l2jserver.service.game.character.CannotSetTargetServiceException; import com.l2jserver.service.game.character.CannotSetTargetServiceException;
import com.l2jserver.service.game.character.CharacterAction; import com.l2jserver.service.game.character.CharacterAction;
import com.l2jserver.service.game.character.CharacterInventoryItemDoesNotExistException;
import com.l2jserver.service.game.character.CharacterInventoryItemExistsException;
import com.l2jserver.service.game.item.ItemNotOnGroundServiceException; import com.l2jserver.service.game.item.ItemNotOnGroundServiceException;
import com.l2jserver.service.game.item.ItemService; import com.l2jserver.service.game.item.ItemService;
import com.l2jserver.service.game.npc.ActionServiceException; import com.l2jserver.service.game.npc.ActionServiceException;
@@ -129,7 +131,9 @@ public class CM_CHAR_ACTION extends AbstractClientPacket {
.getName()); .getName());
conn.sendActionFailed(); conn.sendActionFailed();
} catch (ItemNotOnGroundServiceException } catch (ItemNotOnGroundServiceException
| NotSpawnedServiceException e) { | NotSpawnedServiceException
| CharacterInventoryItemExistsException
| CharacterInventoryItemDoesNotExistException e) {
conn.sendSystemMessage(SystemMessage.FAILED_TO_PICKUP_S1, item conn.sendSystemMessage(SystemMessage.FAILED_TO_PICKUP_S1, item
.getTemplate().getName()); .getTemplate().getName());
conn.sendActionFailed(); conn.sendActionFailed();

View File

@@ -100,6 +100,5 @@ public class CM_CHAR_CHAT extends AbstractClientPacket {
} catch (ChatTargetOfflineServiceException e) { } catch (ChatTargetOfflineServiceException e) {
conn.sendSystemMessage(SystemMessage.S1_IS_NOT_ONLINE, target); conn.sendSystemMessage(SystemMessage.S1_IS_NOT_ONLINE, target);
} }
} }
} }

View File

@@ -28,6 +28,7 @@ import com.l2jserver.model.world.L2Character;
import com.l2jserver.service.game.character.ShortcutService; import com.l2jserver.service.game.character.ShortcutService;
import com.l2jserver.service.game.character.ShortcutSlotNotFreeServiceException; import com.l2jserver.service.game.character.ShortcutSlotNotFreeServiceException;
import com.l2jserver.service.network.model.Lineage2Client; import com.l2jserver.service.network.model.Lineage2Client;
import com.l2jserver.service.network.model.ProtocolVersion;
import com.l2jserver.service.network.model.packet.AbstractClientPacket; import com.l2jserver.service.network.model.packet.AbstractClientPacket;
/** /**
@@ -96,7 +97,11 @@ public class CM_CHAR_SHORTCUT_CREATE extends AbstractClientPacket {
int slot = buffer.readInt(); int slot = buffer.readInt();
objectId = buffer.readInt(); objectId = buffer.readInt();
level = buffer.readInt(); level = buffer.readInt();
// actorType = ShortcutActorType.fromID(buffer.readInt()); FIXME interlude needs this?
// FIXME interlude needs this?
if (conn.supports(ProtocolVersion.FREYA)) {
actorType = ShortcutActorType.fromID(buffer.readInt());
}
this.slot = slot % 12; this.slot = slot % 12;
this.page = slot / 12; this.page = slot / 12;
@@ -117,7 +122,7 @@ public class CM_CHAR_SHORTCUT_CREATE extends AbstractClientPacket {
shortcutService.create(character, item, page, slot); shortcutService.create(character, item, page, slot);
break; break;
} }
//TODO action, macro, recipe // TODO action, macro, recipe
} catch (ShortcutSlotNotFreeServiceException e) { } catch (ShortcutSlotNotFreeServiceException e) {
conn.sendActionFailed(); conn.sendActionFailed();
} }

View File

@@ -22,6 +22,7 @@ import com.google.inject.Inject;
import com.l2jserver.model.id.object.ItemID; import com.l2jserver.model.id.object.ItemID;
import com.l2jserver.model.id.object.provider.ItemIDProvider; import com.l2jserver.model.id.object.provider.ItemIDProvider;
import com.l2jserver.model.world.Item; import com.l2jserver.model.world.Item;
import com.l2jserver.service.game.character.CharacterInventoryItemDoesNotExistException;
import com.l2jserver.service.game.item.ItemService; import com.l2jserver.service.game.item.ItemService;
import com.l2jserver.service.game.item.NonStackableItemsServiceException; import com.l2jserver.service.game.item.NonStackableItemsServiceException;
import com.l2jserver.service.game.item.NotEnoughItemsServiceException; import com.l2jserver.service.game.item.NotEnoughItemsServiceException;
@@ -98,7 +99,8 @@ public class CM_ITEM_DESTROY extends AbstractClientPacket {
conn.updateInventoryItems(item); conn.updateInventoryItems(item);
} }
} catch (NotEnoughItemsServiceException } catch (NotEnoughItemsServiceException
| NonStackableItemsServiceException e) { | NonStackableItemsServiceException
| CharacterInventoryItemDoesNotExistException e) {
conn.sendSystemMessage(SystemMessage.CANNOT_DISCARD_THIS_ITEM); conn.sendSystemMessage(SystemMessage.CANNOT_DISCARD_THIS_ITEM);
} }
} }

View File

@@ -22,6 +22,7 @@ import com.google.inject.Inject;
import com.l2jserver.model.id.object.ItemID; import com.l2jserver.model.id.object.ItemID;
import com.l2jserver.model.id.object.provider.ItemIDProvider; import com.l2jserver.model.id.object.provider.ItemIDProvider;
import com.l2jserver.model.world.Item; import com.l2jserver.model.world.Item;
import com.l2jserver.service.game.character.CharacterInventoryItemDoesNotExistException;
import com.l2jserver.service.game.item.ItemAlreadyOnGroundServiceException; import com.l2jserver.service.game.item.ItemAlreadyOnGroundServiceException;
import com.l2jserver.service.game.item.ItemService; import com.l2jserver.service.game.item.ItemService;
import com.l2jserver.service.game.item.NonStackableItemsServiceException; import com.l2jserver.service.game.item.NonStackableItemsServiceException;
@@ -120,7 +121,8 @@ public class CM_ITEM_DROP extends AbstractClientPacket {
| AlreadySpawnedServiceException | AlreadySpawnedServiceException
| SpawnPointNotFoundServiceException | SpawnPointNotFoundServiceException
| NotEnoughItemsServiceException | NotEnoughItemsServiceException
| NonStackableItemsServiceException e) { | NonStackableItemsServiceException
| CharacterInventoryItemDoesNotExistException e) {
conn.sendActionFailed(); conn.sendActionFailed();
} }
} }

View File

@@ -24,7 +24,6 @@ import org.slf4j.LoggerFactory;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.l2jserver.L2JConstant; import com.l2jserver.L2JConstant;
import com.l2jserver.game.net.InterludeLineage2Client;
import com.l2jserver.game.net.packet.server.SM_KEY; import com.l2jserver.game.net.packet.server.SM_KEY;
import com.l2jserver.service.network.keygen.BlowfishKeygenService; import com.l2jserver.service.network.keygen.BlowfishKeygenService;
import com.l2jserver.service.network.model.Lineage2Client; import com.l2jserver.service.network.model.Lineage2Client;
@@ -86,9 +85,7 @@ public class CM_PROTOCOL_VERSION extends AbstractClientPacket {
final Lineage2CryptographyKey inKey = new Lineage2CryptographyKey( final Lineage2CryptographyKey inKey = new Lineage2CryptographyKey(
keygen.generate()); keygen.generate());
final InterludeLineage2Client client = (InterludeLineage2Client) conn; conn.enableDecrypter(inKey);
client.getDecrypter().enable(inKey);
final Lineage2CryptographyKey outKey = inKey.copy(); final Lineage2CryptographyKey outKey = inKey.copy();
log.debug("Decrypter has been enabled"); log.debug("Decrypter has been enabled");
@@ -117,8 +114,7 @@ public class CM_PROTOCOL_VERSION extends AbstractClientPacket {
throws Exception { throws Exception {
log.debug("Encrypter has been enabled"); log.debug("Encrypter has been enabled");
// enable encrypter // enable encrypter
client.getEncrypter().setKey(outKey); conn.enableEncrypter(outKey);
client.getEncrypter().setEnabled(true);
} }
}); });
} }

View File

@@ -41,6 +41,7 @@ import com.l2jserver.model.world.L2Character;
import com.l2jserver.model.world.actor.ActorExperience; import com.l2jserver.model.world.actor.ActorExperience;
import com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll; import com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll;
import com.l2jserver.service.network.model.Lineage2Client; import com.l2jserver.service.network.model.Lineage2Client;
import com.l2jserver.service.network.model.ProtocolVersion;
import com.l2jserver.service.network.model.packet.AbstractServerPacket; import com.l2jserver.service.network.model.packet.AbstractServerPacket;
import com.l2jserver.util.BufferUtils; import com.l2jserver.util.BufferUtils;
@@ -81,7 +82,7 @@ public class SM_CHAR_INFO extends AbstractServerPacket {
buffer.writeInt(character.getPoint().getX()); buffer.writeInt(character.getPoint().getX());
buffer.writeInt(character.getPoint().getY()); buffer.writeInt(character.getPoint().getY());
buffer.writeInt(character.getPoint().getZ()); buffer.writeInt(character.getPoint().getZ());
buffer.writeInt((int)character.getPoint().getAngle()); buffer.writeInt((int) character.getPoint().getAngle());
buffer.writeInt(character.getID().getID()); buffer.writeInt(character.getID().getID());
BufferUtils.writeString(buffer, character.getName()); BufferUtils.writeString(buffer, character.getName());
buffer.writeInt(character.getRace().id); buffer.writeInt(character.getRace().id);
@@ -195,8 +196,10 @@ public class SM_CHAR_INFO extends AbstractServerPacket {
buffer.writeInt(character.getStats().getRunSpeed()); buffer.writeInt(character.getStats().getRunSpeed());
buffer.writeInt(character.getStats().getWalkSpeed()); buffer.writeInt(character.getStats().getWalkSpeed());
buffer.writeInt(character.getStats().getRunSpeed()); // runspeed in water TODO buffer.writeInt(character.getStats().getRunSpeed()); // runspeed in
buffer.writeInt(character.getStats().getWalkSpeed()); //walkspeed in water TODO // water TODO
buffer.writeInt(character.getStats().getWalkSpeed()); // walkspeed in
// water TODO
buffer.writeInt(0); // unk buffer.writeInt(0); // unk
buffer.writeInt(0); // unk buffer.writeInt(0); // unk
buffer.writeInt(0); // fly speed -only if flying buffer.writeInt(0); // fly speed -only if flying
@@ -243,7 +246,7 @@ public class SM_CHAR_INFO extends AbstractServerPacket {
// 0x40 leader rights // 0x40 leader rights
// siege flags: attacker - 0x180 sword over name, defender - 0x80 // siege flags: attacker - 0x180 sword over name, defender - 0x80
// shield, 0xC0 crown (|leader), 0x1C0 flag (|leader) // shield, 0xC0 crown (|leader), 0x1C0 flag (|leader)
buffer.writeInt(0x40); //relation?? buffer.writeInt(0x40); // relation??
buffer.writeByte(0x00); // mount type buffer.writeByte(0x00); // mount type
buffer.writeByte(0x00); // private store type buffer.writeByte(0x00); // private store type
buffer.writeByte(0x00); // dwarven craft buffer.writeByte(0x00); // dwarven craft
@@ -300,25 +303,27 @@ public class SM_CHAR_INFO extends AbstractServerPacket {
// cursed weapon ID equipped // cursed weapon ID equipped
buffer.writeInt(0x00); buffer.writeInt(0x00);
// // T1 Starts // // T1 Starts
// buffer.writeInt(0x00); // transformation id if (conn.supports(ProtocolVersion.FREYA)) {
// buffer.writeInt(0x00); // transformation id
// buffer.writeShort(0x00); // attack element
// buffer.writeShort(0x10); // attack element value buffer.writeShort(0x00); // attack element
// buffer.writeShort(0x10); // fire defense value buffer.writeShort(0x10); // attack element value
// buffer.writeShort(0x10); // water def value buffer.writeShort(0x10); // fire defense value
// buffer.writeShort(0x10); // wind def value buffer.writeShort(0x10); // water def value
// buffer.writeShort(0x10); // earth def value buffer.writeShort(0x10); // wind def value
// buffer.writeShort(0x10); // holy def value buffer.writeShort(0x10); // earth def value
// buffer.writeShort(0x10); // dark def value buffer.writeShort(0x10); // holy def value
// buffer.writeShort(0x10); // dark def value
// buffer.writeInt(0x00); // getAgathionId
// buffer.writeInt(0x00); // getAgathionId
// // T2 Starts
// buffer.writeInt(0x00); // Fame // T2 Starts
// buffer.writeInt(0x01); // Minimap on Hellbound buffer.writeInt(0x00); // Fame
// buffer.writeInt(1); // Vitality Points buffer.writeInt(0x01); // Minimap on Hellbound
// buffer.writeInt(0x00); // special effects buffer.writeInt(1); // Vitality Points
buffer.writeInt(0x00); // special effects
}
} }
/** /**

View File

@@ -31,9 +31,14 @@ import static com.l2jserver.model.world.character.CharacterInventory.InventoryPa
import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.HAIR2; import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.HAIR2;
import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.HEAD; import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.HEAD;
import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.LEFT_BRACELET; import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.LEFT_BRACELET;
import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.LEFT_EAR;
import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.LEFT_FINGER;
import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.LEFT_HAND; import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.LEFT_HAND;
import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.LEGS; import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.LEGS;
import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.NECK;
import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.RIGHT_BRACELET; import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.RIGHT_BRACELET;
import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.RIGHT_EAR;
import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.RIGHT_FINGER;
import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.RIGHT_HAND; import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.RIGHT_HAND;
import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.UNDERWEAR; import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.UNDERWEAR;
@@ -45,6 +50,7 @@ import com.l2jserver.model.world.L2Character;
import com.l2jserver.model.world.L2Character.CharacterMoveType; import com.l2jserver.model.world.L2Character.CharacterMoveType;
import com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll; import com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll;
import com.l2jserver.service.network.model.Lineage2Client; import com.l2jserver.service.network.model.Lineage2Client;
import com.l2jserver.service.network.model.ProtocolVersion;
import com.l2jserver.service.network.model.packet.AbstractServerPacket; import com.l2jserver.service.network.model.packet.AbstractServerPacket;
import com.l2jserver.util.BufferUtils; import com.l2jserver.util.BufferUtils;
@@ -87,11 +93,13 @@ public class SM_CHAR_INFO_BROADCAST extends AbstractServerPacket {
buffer.writeInt(character.getCharacterClass().id); buffer.writeInt(character.getCharacterClass().id);
writePaperdollItemID(buffer, character, UNDERWEAR); writePaperdollItemID(buffer, character, UNDERWEAR);
// writePaperdollItemID(buffer, character, RIGHT_EAR); if (conn.supports(ProtocolVersion.FREYA)) {
// writePaperdollItemID(buffer, character, LEFT_EAR); writePaperdollItemID(buffer, character, RIGHT_EAR);
// writePaperdollItemID(buffer, character, NECK); writePaperdollItemID(buffer, character, LEFT_EAR);
// writePaperdollItemID(buffer, character, RIGHT_FINGER); writePaperdollItemID(buffer, character, NECK);
// writePaperdollItemID(buffer, character, LEFT_FINGER); writePaperdollItemID(buffer, character, RIGHT_FINGER);
writePaperdollItemID(buffer, character, LEFT_FINGER);
}
writePaperdollItemID(buffer, character, HEAD); writePaperdollItemID(buffer, character, HEAD);
writePaperdollItemID(buffer, character, RIGHT_HAND); writePaperdollItemID(buffer, character, RIGHT_HAND);
writePaperdollItemID(buffer, character, LEFT_HAND); writePaperdollItemID(buffer, character, LEFT_HAND);
@@ -114,11 +122,13 @@ public class SM_CHAR_INFO_BROADCAST extends AbstractServerPacket {
writePaperdollItemID(buffer, character, BELT); writePaperdollItemID(buffer, character, BELT);
writePaperdollAugumentID(buffer, character, UNDERWEAR); writePaperdollAugumentID(buffer, character, UNDERWEAR);
// writePaperdollAugumentID(buffer, character, RIGHT_EAR); if (conn.supports(ProtocolVersion.FREYA)) {
// writePaperdollAugumentID(buffer, character, LEFT_EAR); writePaperdollAugumentID(buffer, character, RIGHT_EAR);
// writePaperdollAugumentID(buffer, character, NECK); writePaperdollAugumentID(buffer, character, LEFT_EAR);
// writePaperdollAugumentID(buffer, character, RIGHT_FINGER); writePaperdollAugumentID(buffer, character, NECK);
// writePaperdollAugumentID(buffer, character, LEFT_FINGER); writePaperdollAugumentID(buffer, character, RIGHT_FINGER);
writePaperdollAugumentID(buffer, character, LEFT_FINGER);
}
writePaperdollAugumentID(buffer, character, HEAD); writePaperdollAugumentID(buffer, character, HEAD);
writePaperdollAugumentID(buffer, character, RIGHT_HAND); writePaperdollAugumentID(buffer, character, RIGHT_HAND);
writePaperdollAugumentID(buffer, character, LEFT_HAND); writePaperdollAugumentID(buffer, character, LEFT_HAND);

View File

@@ -22,6 +22,7 @@ import com.l2jserver.model.world.Item;
import com.l2jserver.model.world.character.CharacterInventory; import com.l2jserver.model.world.character.CharacterInventory;
import com.l2jserver.model.world.character.CharacterInventory.ItemLocation; import com.l2jserver.model.world.character.CharacterInventory.ItemLocation;
import com.l2jserver.service.network.model.Lineage2Client; import com.l2jserver.service.network.model.Lineage2Client;
import com.l2jserver.service.network.model.ProtocolVersion;
import com.l2jserver.service.network.model.packet.AbstractServerPacket; import com.l2jserver.service.network.model.packet.AbstractServerPacket;
/** /**
@@ -59,11 +60,15 @@ public class SM_CHAR_INVENTORY extends AbstractServerPacket {
// TODO warehouse items will have an issue here! // TODO warehouse items will have an issue here!
buffer.writeShort(inventory.getItemCount()); // item count buffer.writeShort(inventory.getItemCount()); // item count
int slot = 0;
for (Item item : inventory) { for (Item item : inventory) {
buffer.writeShort(0x00); // "item type1" - whatever that is. check l2j TODO buffer.writeShort(0x00); // "item type1" - whatever that is. check
// l2j TODO
buffer.writeInt(item.getID().getID()); // obj id buffer.writeInt(item.getID().getID()); // obj id
buffer.writeInt(item.getTemplateID().getID()); // item id buffer.writeInt(item.getTemplateID().getID()); // item id
//buffer.writeInt(slot); // loc slot if (conn.supports(ProtocolVersion.FREYA)) {
buffer.writeInt(slot); // loc slot
}
buffer.writeLong(item.getCount()); // count buffer.writeLong(item.getCount()); // count
buffer.writeShort(0x00); // item type2 buffer.writeShort(0x00); // item type2
buffer.writeShort(0x00); // item type3 buffer.writeShort(0x00); // item type3
@@ -73,8 +78,35 @@ public class SM_CHAR_INVENTORY extends AbstractServerPacket {
: 0)); // body part : 0)); // body part
buffer.writeShort(127); // enchant level buffer.writeShort(127); // enchant level
// race tickets // race tickets
if(conn.supports(ProtocolVersion.FREYA)) {
buffer.writeShort(0x00); // item type4 (custom type 2)
}
buffer.writeInt(0x00); // AugmentationId TODO buffer.writeInt(0x00); // AugmentationId TODO
if(conn.supports(ProtocolVersion.FREYA)) {
buffer.writeInt(0x00); // mana
}
buffer.writeInt(0x00); // Remaining shadow item time TODO buffer.writeInt(0x00); // Remaining shadow item time TODO
if(conn.supports(ProtocolVersion.FREYA)) {
buffer.writeShort(0x00); // attack element type
buffer.writeShort(0x00); // attack element power
for (byte i = 0; i < 6; i++) {
buffer.writeShort(0x00); // element def attrib
}
// Enchant Effects
buffer.writeShort(0x00);
buffer.writeShort(0x00);
buffer.writeShort(0x00);
}
slot++;
}
if(conn.supports(ProtocolVersion.FREYA)) {
buffer.writeShort(0x00);
} }
} }
} }

View File

@@ -50,6 +50,7 @@ import com.l2jserver.model.world.L2Character;
import com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll; import com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll;
import com.l2jserver.service.network.model.Lineage2Client; import com.l2jserver.service.network.model.Lineage2Client;
import com.l2jserver.service.network.model.Lineage2Session; import com.l2jserver.service.network.model.Lineage2Session;
import com.l2jserver.service.network.model.ProtocolVersion;
import com.l2jserver.service.network.model.packet.AbstractServerPacket; import com.l2jserver.service.network.model.packet.AbstractServerPacket;
import com.l2jserver.util.BufferUtils; import com.l2jserver.util.BufferUtils;
@@ -62,7 +63,7 @@ public class SM_CHAR_LIST extends AbstractServerPacket {
/** /**
* The packet OPCODE * The packet OPCODE
*/ */
public static final int OPCODE = 0x09; public static final int OPCODE = 0x13;
/** /**
* The account username * The account username
@@ -125,35 +126,31 @@ public class SM_CHAR_LIST extends AbstractServerPacket {
@Override @Override
public void write(Lineage2Client conn, ChannelBuffer buffer) { public void write(Lineage2Client conn, ChannelBuffer buffer) {
// buffer.writeByte(0x09);
buffer.writeInt(characters.length); buffer.writeInt(characters.length);
// Can prevent players from creating new characters (if 0); // Can prevent players from creating new characters (if 0);
// if 1 the client will ask if chars may be created // if 1 the client will ask if chars may be created
// (RequestCharacterTemplatesPacket) Response: (CharacterTemplatePacket) // (RequestCharacterTemplatesPacket) Response: (CharacterTemplatePacket)
if (conn.supports(ProtocolVersion.FREYA)) {
buffer.writeInt(7); // max chars buffer.writeInt(7); // max chars
buffer.writeByte(0x00); buffer.writeByte(0x00);
}
// int i = 0;
for (final L2Character character : characters) { for (final L2Character character : characters) {
BufferUtils.writeString(buffer, character.getName()); BufferUtils.writeString(buffer, character.getName());
buffer.writeInt(character.getID().getID()); buffer.writeInt(character.getID().getID());
BufferUtils.writeString(buffer, loginName); BufferUtils.writeString(buffer, loginName);
buffer.writeInt(sessionId); buffer.writeInt(sessionId);
buffer.writeInt((character.getClanID() != null ? character buffer.writeInt((character.getClanID() != null ? character
.getClanID().getID() : 0x00)); // clan id .getClanID().getID() : 0x01));
buffer.writeInt(0x00); // ?? buffer.writeInt(0x00);
buffer.writeInt(character.getSex().option); // sex buffer.writeInt(character.getSex().option);
buffer.writeInt(character.getRace().id); // race buffer.writeInt(character.getRace().id);
// if (character.getClassId() == character.getBaseClassId()) buffer.writeInt(character.getCharacterClass().id);
buffer.writeInt(character.getCharacterClass().id); // base class id
// or class id
// else
// buffer.writeInt(character.getBaseClassId());
buffer.writeInt(1); // active ?? buffer.writeInt(0x01); // active
buffer.writeInt(character.getPoint().getX()); // x buffer.writeInt(character.getPoint().getX()); // x
buffer.writeInt(character.getPoint().getY()); // y buffer.writeInt(character.getPoint().getY()); // y
@@ -170,16 +167,13 @@ public class SM_CHAR_LIST extends AbstractServerPacket {
buffer.writeInt(character.getPkKills()); // pk buffer.writeInt(character.getPkKills()); // pk
buffer.writeInt(character.getPvpKills()); // pvp buffer.writeInt(character.getPvpKills()); // pvp
for (int n = 0; n < 7; n++) { buffer.writeInt(0x00);
buffer.writeInt(0x00); // unk buffer.writeInt(0x00);
} buffer.writeInt(0x00);
// buffer.writeInt(0x00); // unk 1 buffer.writeInt(0x00);
// buffer.writeInt(0x00); // unk 2 buffer.writeInt(0x00);
// buffer.writeInt(0x00); // unk 3 buffer.writeInt(0x00);
// buffer.writeInt(0x00); // unk 4 buffer.writeInt(0x00);
// buffer.writeInt(0x00); // unk 5
// buffer.writeInt(0x00); // unk 6
// buffer.writeInt(0x00); // unk 7
writePaperdollItemID(buffer, character, HAIR1); writePaperdollItemID(buffer, character, HAIR1);
writePaperdollItemID(buffer, character, RIGHT_EAR); writePaperdollItemID(buffer, character, RIGHT_EAR);
@@ -198,6 +192,8 @@ public class SM_CHAR_LIST extends AbstractServerPacket {
writePaperdollItemID(buffer, character, RIGHT_HAND); writePaperdollItemID(buffer, character, RIGHT_HAND);
writePaperdollItemID(buffer, character, HAIR1); writePaperdollItemID(buffer, character, HAIR1);
writePaperdollItemID(buffer, character, HAIR2); writePaperdollItemID(buffer, character, HAIR2);
if (conn.supports(ProtocolVersion.FREYA)) {
writePaperdollItemID(buffer, character, RIGHT_BRACELET); writePaperdollItemID(buffer, character, RIGHT_BRACELET);
writePaperdollItemID(buffer, character, LEFT_BRACELET); writePaperdollItemID(buffer, character, LEFT_BRACELET);
writePaperdollItemID(buffer, character, DECORATION_1); writePaperdollItemID(buffer, character, DECORATION_1);
@@ -207,6 +203,29 @@ public class SM_CHAR_LIST extends AbstractServerPacket {
writePaperdollItemID(buffer, character, DECORATION_5); writePaperdollItemID(buffer, character, DECORATION_5);
writePaperdollItemID(buffer, character, DECORATION_6); writePaperdollItemID(buffer, character, DECORATION_6);
writePaperdollItemID(buffer, character, BELT); writePaperdollItemID(buffer, character, BELT);
}
if (conn.supports(ProtocolVersion.RELEASE,
ProtocolVersion.INTERLUDE)) {
// duplicated to "fill the packet space".
writePaperdollItemID(buffer, character, HAIR1);
writePaperdollItemID(buffer, character, RIGHT_EAR);
writePaperdollItemID(buffer, character, LEFT_EAR);
writePaperdollItemID(buffer, character, NECK);
writePaperdollItemID(buffer, character, RIGHT_FINGER);
writePaperdollItemID(buffer, character, LEFT_FINGER);
writePaperdollItemID(buffer, character, HEAD);
writePaperdollItemID(buffer, character, RIGHT_HAND);
writePaperdollItemID(buffer, character, LEFT_HAND);
writePaperdollItemID(buffer, character, GLOVES);
writePaperdollItemID(buffer, character, CHEST);
writePaperdollItemID(buffer, character, LEGS);
writePaperdollItemID(buffer, character, FEET);
writePaperdollItemID(buffer, character, CLOAK);
writePaperdollItemID(buffer, character, RIGHT_HAND);
writePaperdollItemID(buffer, character, HAIR1);
writePaperdollItemID(buffer, character, HAIR2);
}
// hair style // hair style
buffer.writeInt(character.getAppearance().getHairStyle().option); buffer.writeInt(character.getAppearance().getHairStyle().option);
@@ -214,19 +233,26 @@ public class SM_CHAR_LIST extends AbstractServerPacket {
buffer.writeInt(character.getAppearance().getHairColor().option); buffer.writeInt(character.getAppearance().getHairColor().option);
// face // face
buffer.writeInt(character.getAppearance().getFace().option); buffer.writeInt(character.getAppearance().getFace().option);
// max hp
buffer.writeDouble(character.getStats().getMaxHP());
// max mp
buffer.writeDouble(character.getStats().getMaxMP());
buffer.writeDouble(character.getStats().getMaxHP()); // hp max // time left before character is deleted (in seconds?) TODO
buffer.writeDouble(character.getStats().getMaxMP()); // mp max buffer.writeInt(0x00);
buffer.writeInt(0x0); // seconds left before delete buffer.writeInt(character.getCharacterClass().id);
buffer.writeInt(character.getCharacterClass().id); // class
buffer.writeInt(1); // c3 auto-select char
buffer.writeByte(0x00); // enchant effect // 0x01 auto selects this character. TODO
buffer.writeInt(0x00);
// enchant effect TODO
buffer.writeByte(0x16);
// augmentation id
buffer.writeInt(0x00);
buffer.writeInt(0x00); // augmentation id if (conn.supports(ProtocolVersion.FREYA)) {
// Currently on retail when you are on character select you
// Currently on retail when you are on character select you don't // don't
// see your transformation. // see your transformation.
buffer.writeInt(0x00); buffer.writeInt(0x00);
@@ -240,6 +266,7 @@ public class SM_CHAR_LIST extends AbstractServerPacket {
buffer.writeDouble(0); // cur Hp buffer.writeDouble(0); // cur Hp
} }
} }
}
/** /**
* Writes the paperdoll item id * Writes the paperdoll item id

View File

@@ -21,6 +21,7 @@ import org.jboss.netty.buffer.ChannelBuffer;
import com.l2jserver.model.world.L2Character; import com.l2jserver.model.world.L2Character;
import com.l2jserver.model.world.actor.ActorExperience; import com.l2jserver.model.world.actor.ActorExperience;
import com.l2jserver.service.network.model.Lineage2Client; import com.l2jserver.service.network.model.Lineage2Client;
import com.l2jserver.service.network.model.ProtocolVersion;
import com.l2jserver.service.network.model.packet.AbstractServerPacket; import com.l2jserver.service.network.model.packet.AbstractServerPacket;
import com.l2jserver.util.BufferUtils; import com.l2jserver.util.BufferUtils;
@@ -81,8 +82,22 @@ public class SM_CHAR_SELECTED extends AbstractServerPacket {
buffer.writeInt(character.getStats().getDexterity()); buffer.writeInt(character.getStats().getDexterity());
buffer.writeInt(character.getStats().getWitness()); buffer.writeInt(character.getStats().getWitness());
for(int i = 0; i < 30; i++) // TODO this really needs some refining!
{ if (conn.supports(ProtocolVersion.FREYA)) {
buffer.writeInt(0); // game time
buffer.writeInt(0x00); // unk
buffer.writeInt(character.getCharacterClass().id);
buffer.writeInt(0x00);// unk
buffer.writeInt(0x00);// unk
buffer.writeInt(0x00);// unk
buffer.writeInt(0x00);// unk
buffer.writeBytes(new byte[64]); // unk
buffer.writeInt(0x00);// unk
} else {
for (int i = 0; i < 30; i++) {
buffer.writeInt(0x00); buffer.writeInt(0x00);
} }
@@ -106,4 +121,5 @@ public class SM_CHAR_SELECTED extends AbstractServerPacket {
buffer.writeInt(0x00); buffer.writeInt(0x00);
buffer.writeInt(0x00); buffer.writeInt(0x00);
} }
}
} }

View File

@@ -20,6 +20,7 @@ import org.jboss.netty.buffer.ChannelBuffer;
import com.l2jserver.model.game.CharacterShortcut; import com.l2jserver.model.game.CharacterShortcut;
import com.l2jserver.service.network.model.Lineage2Client; import com.l2jserver.service.network.model.Lineage2Client;
import com.l2jserver.service.network.model.ProtocolVersion;
import com.l2jserver.service.network.model.packet.AbstractServerPacket; import com.l2jserver.service.network.model.packet.AbstractServerPacket;
/** /**
@@ -54,12 +55,14 @@ public class SM_CHAR_SHORTCUT_REGISTER extends AbstractServerPacket {
switch (shortcut.getType()) { switch (shortcut.getType()) {
case ITEM: case ITEM:
buffer.writeInt(shortcut.getItemID().getID()); buffer.writeInt(shortcut.getItemID().getID());
// buffer.writeInt(0x01); // unk1f if (conn.supports(ProtocolVersion.FREYA)) {
// buffer.writeInt(-1); // reuse group buffer.writeInt(0x01); // unk1f
// buffer.writeInt(0x00); // unk2 buffer.writeInt(-1); // reuse group
// buffer.writeInt(0x00); // unk3 buffer.writeInt(0x00); // unk2
// buffer.writeShort(0x00); // unk4 buffer.writeInt(0x00); // unk3
// buffer.writeShort(0x00); // unk5 buffer.writeShort(0x00); // unk4
buffer.writeShort(0x00); // unk5
}
break; break;
default: default:
buffer.writeInt(shortcut.getID().getID()); buffer.writeInt(shortcut.getID().getID());

View File

@@ -21,6 +21,7 @@ import org.jboss.netty.buffer.ChannelBuffer;
import com.l2jserver.model.template.NPCTemplate; import com.l2jserver.model.template.NPCTemplate;
import com.l2jserver.model.world.NPC; import com.l2jserver.model.world.NPC;
import com.l2jserver.service.network.model.Lineage2Client; import com.l2jserver.service.network.model.Lineage2Client;
import com.l2jserver.service.network.model.ProtocolVersion;
import com.l2jserver.service.network.model.packet.AbstractServerPacket; import com.l2jserver.service.network.model.packet.AbstractServerPacket;
import com.l2jserver.util.BufferUtils; import com.l2jserver.util.BufferUtils;
@@ -120,5 +121,20 @@ public class SM_NPC_INFO extends AbstractServerPacket {
buffer.writeDouble(template.getInfo().getCollision().getHeigth()); buffer.writeDouble(template.getInfo().getCollision().getHeigth());
buffer.writeInt(0x00); // C4 - enchant effect buffer.writeInt(0x00); // C4 - enchant effect
buffer.writeInt(0x00); // C6 -- is flying buffer.writeInt(0x00); // C6 -- is flying
if (conn.supports(ProtocolVersion.FREYA)) {
buffer.writeInt(0x00); // unk
buffer.writeInt(0x00);// CT1.5 Pet form and skills, Color effect
buffer.writeByte((template.getInfo().getName() != null
&& template.getInfo().getName().isDisplay() ? 0x01 : 0x00)); // hide
// name
buffer.writeByte((template.getInfo().getName() != null
&& template.getInfo().getName().isDisplay() ? 0x01 : 0x00)); // hide
// name,
// again
buffer.writeInt(0x00); // special effects
buffer.writeInt(0x00); // display effect
}
} }
} }

View File

@@ -155,6 +155,21 @@ public class CharacterInventory implements Iterable<Item> {
return getItem(paperdoll) != null; return getItem(paperdoll) != null;
} }
/**
* Checks if the given item is already on the character's inventory
*
* @param item
* the item
* @return true if has the item
*/
public boolean has(Item item) {
for(final Item checkItem : items) {
if(checkItem.getID().equals(item.getID()))
return true;
}
return false;
}
/** /**
* This method will add new items to the inventory. This is normally called * This method will add new items to the inventory. This is normally called
* from the DAO object. * from the DAO object.

View File

@@ -0,0 +1,85 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.model.world.item;
import com.l2jserver.model.id.ObjectID;
import com.l2jserver.model.world.Actor;
import com.l2jserver.model.world.Item;
import com.l2jserver.model.world.L2Character;
import com.l2jserver.model.world.Player;
import com.l2jserver.model.world.WorldObject;
import com.l2jserver.model.world.character.event.CharacterEvent;
/**
* Event dispatched once an {@link Item} has been created directly into the
* player's inventory
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class ItemCreatedEvent implements ItemEvent, CharacterEvent {
/**
* The character character owning the item
*/
private final L2Character character;
/**
* The item created
*/
private final Item item;
/**
* Creates a new instance of this event
*
* @param character
* the character who owns the item (if any)
* @param item
* the created item
*/
public ItemCreatedEvent(L2Character character, Item item) {
this.character = character;
this.item = item;
}
@Override
public WorldObject getObject() {
return item;
}
@Override
public L2Character getCharacter() {
return character;
}
@Override
public Player getPlayer() {
return character;
}
@Override
public Item getItem() {
return item;
}
@Override
public Actor getActor() {
return character;
}
@Override
public ObjectID<?>[] getDispatchableObjects() {
return new ObjectID<?>[] { item.getID() };
}
}

View File

@@ -0,0 +1,85 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.model.world.item;
import com.l2jserver.model.id.ObjectID;
import com.l2jserver.model.world.Actor;
import com.l2jserver.model.world.Item;
import com.l2jserver.model.world.L2Character;
import com.l2jserver.model.world.Player;
import com.l2jserver.model.world.WorldObject;
import com.l2jserver.model.world.character.event.CharacterEvent;
/**
* Event dispatched once an {@link Item} has been removed directly from the
* player's inventory
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class ItemRemovedEvent implements ItemEvent, CharacterEvent {
/**
* The character character owning the item
*/
private final L2Character character;
/**
* The item removed
*/
private final Item item;
/**
* Creates a new instance of this event
*
* @param character
* the character that owned the item (if any)
* @param item
* the destroyed item
*/
public ItemRemovedEvent(L2Character character, Item item) {
this.character = character;
this.item = item;
}
@Override
public WorldObject getObject() {
return item;
}
@Override
public L2Character getCharacter() {
return character;
}
@Override
public Player getPlayer() {
return character;
}
@Override
public Item getItem() {
return item;
}
@Override
public Actor getActor() {
return character;
}
@Override
public ObjectID<?>[] getDispatchableObjects() {
return new ObjectID<?>[] { item.getID() };
}
}

View File

@@ -23,11 +23,13 @@ import org.slf4j.LoggerFactory;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.l2jserver.model.id.object.CharacterID; import com.l2jserver.model.id.object.CharacterID;
import com.l2jserver.model.id.template.ItemTemplateID;
import com.l2jserver.model.id.template.provider.ItemTemplateIDProvider; import com.l2jserver.model.id.template.provider.ItemTemplateIDProvider;
import com.l2jserver.model.world.Actor; import com.l2jserver.model.world.Actor;
import com.l2jserver.model.world.L2Character; import com.l2jserver.model.world.L2Character;
import com.l2jserver.service.AbstractService; import com.l2jserver.service.AbstractService;
import com.l2jserver.service.ServiceException; import com.l2jserver.service.ServiceException;
import com.l2jserver.service.game.character.CharacterInventoryService;
import com.l2jserver.service.game.item.ItemService; import com.l2jserver.service.game.item.ItemService;
import com.l2jserver.service.game.spawn.CharacterAlreadyTeleportingServiceException; import com.l2jserver.service.game.spawn.CharacterAlreadyTeleportingServiceException;
import com.l2jserver.service.game.spawn.NotSpawnedServiceException; import com.l2jserver.service.game.spawn.NotSpawnedServiceException;
@@ -51,25 +53,44 @@ public class AdministratorServiceImpl extends AbstractService implements
*/ */
private final SpawnService spawnService; private final SpawnService spawnService;
/**
* The inventory service
*/
private final CharacterInventoryService inventoryService;
/**
* The Item service
*/
private final ItemService itemService;
/**
* The item template ID provider
*/
private final ItemTemplateIDProvider itemTemplateIdProvider;
/** /**
* List of online administrators * List of online administrators
*/ */
@SuppressWarnings("unused") @SuppressWarnings("unused")
private List<CharacterID> online; private List<CharacterID> online;
@Inject
private ItemService itemService;
@Inject
private ItemTemplateIDProvider itidProvider;
/** /**
* @param spawnService * @param spawnService
* the spawn service * the spawn service
* @param inventoryService
* the inventory service
* @param itemService
* the item service
* @param itemTemplateIdProvider
* the item template id provider
*/ */
@Inject @Inject
private AdministratorServiceImpl(SpawnService spawnService) { private AdministratorServiceImpl(SpawnService spawnService,
CharacterInventoryService inventoryService,
ItemService itemService,
ItemTemplateIDProvider itemTemplateIdProvider) {
this.spawnService = spawnService; this.spawnService = spawnService;
this.inventoryService = inventoryService;
this.itemService = itemService;
this.itemTemplateIdProvider = itemTemplateIdProvider;
} }
@Override @Override
@@ -89,8 +110,28 @@ public class AdministratorServiceImpl extends AbstractService implements
Integer.parseInt(args[2]))); Integer.parseInt(args[2])));
break; break;
case "give": case "give":
// conn.sendMessage( "adding " + itidProvider.resolveID(57).getTemplate().getName() ); L2Character target;
character.getInventory().add( itemService.create(itidProvider.resolveID(57).getTemplate(), 10000) ); if (character.getTarget() instanceof L2Character) {
target = (L2Character) character.getTarget();
} else {
target = character;
}
int count = 1;
ItemTemplateID itemTemplateID;
if (args.length == 1) {
itemTemplateID = itemTemplateIdProvider.resolveID(Integer
.parseInt(args[0]));
} else if (args.length == 2) {
itemTemplateID = itemTemplateIdProvider.resolveID(Integer
.parseInt(args[0]));
count = Integer.parseInt(args[1]);
} else {
throw new ServiceException();
}
inventoryService.add(target,
itemService.create(itemTemplateID.getTemplate(), count));
break; break;
default: default:
throw new ServiceException(); throw new ServiceException();

View File

@@ -0,0 +1,64 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.service.game.character;
/**
* Exception thrown when the character inventory does not contain the requested
* item
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class CharacterInventoryItemDoesNotExistException extends
CharacterServiceException {
/**
* The Java Serialization API serial
*/
private static final long serialVersionUID = 1L;
/**
* Creates a new instance
*/
public CharacterInventoryItemDoesNotExistException() {
}
/**
* @param message
* the message
* @param cause
* the cause
*/
public CharacterInventoryItemDoesNotExistException(String message,
Throwable cause) {
super(message, cause);
}
/**
* @param message
* the message
*/
public CharacterInventoryItemDoesNotExistException(String message) {
super(message);
}
/**
* @param cause
* the cause
*/
public CharacterInventoryItemDoesNotExistException(Throwable cause) {
super(cause);
}
}

View File

@@ -14,37 +14,50 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>. * along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/ */
package com.l2jserver.game.net.packet.server; package com.l2jserver.service.game.character;
import org.jboss.netty.buffer.ChannelBuffer;
import com.l2jserver.service.network.model.Lineage2Client;
import com.l2jserver.service.network.model.packet.AbstractServerPacket;
/** /**
* This packet responds to the Restart request * Exception thrown when the character inventory already contains the requested
* item
* *
* @author <a href="http://www.rogiel.com">Rogiel</a> * @author <a href="http://www.rogiel.com">Rogiel</a>
*/ */
public class SM_ACTION_FAILED extends AbstractServerPacket { public class CharacterInventoryItemExistsException extends
CharacterServiceException {
/** /**
* The packet OPCODE * The Java Serialization API serial
*/ */
public static final int OPCODE = 0x1f; private static final long serialVersionUID = 1L;
/**
* The {@link SM_ACTION_FAILED} shared instance
*/
public static final SM_ACTION_FAILED SHARED_INSTANCE = new SM_ACTION_FAILED();
/** /**
* Creates a new instance * Creates a new instance
*/ */
public SM_ACTION_FAILED() { public CharacterInventoryItemExistsException() {
super(OPCODE);
} }
@Override /**
public void write(Lineage2Client conn, ChannelBuffer buffer) { * @param message
* the message
* @param cause
* the cause
*/
public CharacterInventoryItemExistsException(String message, Throwable cause) {
super(message, cause);
}
/**
* @param message
* the message
*/
public CharacterInventoryItemExistsException(String message) {
super(message);
}
/**
* @param cause
* the cause
*/
public CharacterInventoryItemExistsException(Throwable cause) {
super(cause);
} }
} }

View File

@@ -0,0 +1,71 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.service.game.character;
import com.l2jserver.model.world.Item;
import com.l2jserver.model.world.L2Character;
import com.l2jserver.service.Service;
/**
* This services handles an {@link L2Character} inventory
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public interface CharacterInventoryService extends Service {
/**
* Adds an item to the player inventory
*
* @param character
* the character's whose inventory should be changed
* @param item
* the item to be added to the inventory
* @throws CharacterInventoryItemExistsException
* if the item already exists on the player's inventory
*/
void add(L2Character character, Item item)
throws CharacterInventoryItemExistsException;
/**
* Removes an item from the player inventory
*
* @param character
* the character's whose inventory should be changed
* @param item
* the item to be removed from the inventory
* @throws CharacterInventoryItemDoesNotExistException
* if the <code>item</code> is not present in the player's
* inventory
*/
void remove(L2Character character, Item item)
throws CharacterInventoryItemDoesNotExistException;
/**
* Changes the order of an item into the player's inventory
*
* @param character
* character the character's whose inventory should be changed
* @param item
* the item that will be changed the order
* @param order
* the new order
* @throws CharacterInventoryItemDoesNotExistException
* if the <code>item</code> is not present in the player's
* inventory
*/
void reorder(L2Character character, Item item, int order)
throws CharacterInventoryItemDoesNotExistException;
}

View File

@@ -0,0 +1,70 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.service.game.character;
import com.google.inject.Inject;
import com.l2jserver.model.world.Item;
import com.l2jserver.model.world.L2Character;
import com.l2jserver.model.world.item.ItemCreatedEvent;
import com.l2jserver.model.world.item.ItemRemovedEvent;
import com.l2jserver.service.AbstractService;
import com.l2jserver.service.game.world.WorldService;
import com.l2jserver.service.game.world.event.WorldEventDispatcherService;
/**
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class CharacterInventoryServiceImpl extends AbstractService implements
CharacterInventoryService {
/**
* The {@link WorldService} event dispatcher
*/
private final WorldEventDispatcherService eventDispatcherService;
/**
* @param eventDispatcherService
* the event dispatcher
*/
@Inject
public CharacterInventoryServiceImpl(
WorldEventDispatcherService eventDispatcherService) {
this.eventDispatcherService = eventDispatcherService;
}
@Override
public void add(L2Character character, Item item) {
if (character.getInventory().has(item)) {
// throw an exception
}
character.getInventory().add(item);
eventDispatcherService.dispatch(new ItemCreatedEvent(character, item));
}
@Override
public void remove(L2Character character, Item item) {
if (!character.getInventory().has(item)) {
// throw an exception
}
character.getInventory().add(item);
eventDispatcherService.dispatch(new ItemRemovedEvent(character, item));
}
@Override
public void reorder(L2Character character, Item item, int order) {
// TODO implement item reordering
}
}

View File

@@ -23,6 +23,8 @@ import com.l2jserver.model.world.Item;
import com.l2jserver.model.world.L2Character; import com.l2jserver.model.world.L2Character;
import com.l2jserver.service.Service; import com.l2jserver.service.Service;
import com.l2jserver.service.game.character.CharacterAction; import com.l2jserver.service.game.character.CharacterAction;
import com.l2jserver.service.game.character.CharacterInventoryItemDoesNotExistException;
import com.l2jserver.service.game.character.CharacterInventoryItemExistsException;
import com.l2jserver.service.game.spawn.AlreadySpawnedServiceException; import com.l2jserver.service.game.spawn.AlreadySpawnedServiceException;
import com.l2jserver.service.game.spawn.NotSpawnedServiceException; import com.l2jserver.service.game.spawn.NotSpawnedServiceException;
import com.l2jserver.service.game.spawn.SpawnPointNotFoundServiceException; import com.l2jserver.service.game.spawn.SpawnPointNotFoundServiceException;
@@ -79,9 +81,16 @@ public interface ItemService extends Service {
* if the item is not on ground at the moment * if the item is not on ground at the moment
* @throws NotSpawnedServiceException * @throws NotSpawnedServiceException
* if the item is not registered with {@link SpawnService} * if the item is not registered with {@link SpawnService}
* @throws CharacterInventoryItemExistsException
* if the character's inventory already has the given item added
* to
* @throws CharacterInventoryItemDoesNotExistException
* if the character's inventory does not have the requested item
*/ */
Item action(Item item, L2Character character, CharacterAction action) Item action(Item item, L2Character character, CharacterAction action)
throws ItemNotOnGroundServiceException, NotSpawnedServiceException; throws ItemNotOnGroundServiceException, NotSpawnedServiceException,
CharacterInventoryItemExistsException,
CharacterInventoryItemDoesNotExistException;
/** /**
* Splits this item in two pieces * Splits this item in two pieces
@@ -127,18 +136,24 @@ public interface ItemService extends Service {
* @throws NonStackableItemsServiceException * @throws NonStackableItemsServiceException
* if the item could not be destroyed because it was not * if the item could not be destroyed because it was not
* possible to split it * possible to split it
* @throws CharacterInventoryItemDoesNotExistException
* if the character's inventory does not have the requested item
*/ */
boolean destroy(Item item, long count) boolean destroy(Item item, long count)
throws NotEnoughItemsServiceException, throws NotEnoughItemsServiceException,
NonStackableItemsServiceException; NonStackableItemsServiceException,
CharacterInventoryItemDoesNotExistException;
/** /**
* Destroys several items * Destroys several items
* *
* @param items * @param items
* the items to be destroyed * the items to be destroyed
* @throws CharacterInventoryItemDoesNotExistException
* if the character's inventory does not have the requested item
*/ */
void destroy(Item... items); void destroy(Item... items)
throws CharacterInventoryItemDoesNotExistException;
/** /**
* Picks up an dropped item and places it into another players inventory * Picks up an dropped item and places it into another players inventory
@@ -152,9 +167,15 @@ public interface ItemService extends Service {
* if the item is not on ground at the moment * if the item is not on ground at the moment
* @throws NotSpawnedServiceException * @throws NotSpawnedServiceException
* if the item is not registered with {@link SpawnService} * if the item is not registered with {@link SpawnService}
* @throws CharacterInventoryItemExistsException
* if the character's inventory already has this item added to
* @throws CharacterInventoryItemDoesNotExistException
* if the character's inventory does not have the item added to
*/ */
Item pickUp(Item item, L2Character character) Item pickUp(Item item, L2Character character)
throws ItemNotOnGroundServiceException, NotSpawnedServiceException; throws ItemNotOnGroundServiceException, NotSpawnedServiceException,
CharacterInventoryItemExistsException,
CharacterInventoryItemDoesNotExistException;
/** /**
* Drops an item on the ground. If <code>actor</code> is not * Drops an item on the ground. If <code>actor</code> is not
@@ -181,11 +202,15 @@ public interface ItemService extends Service {
* if <code>count</code> is bigger than {@link Item#getCount()}. * if <code>count</code> is bigger than {@link Item#getCount()}.
* @throws NonStackableItemsServiceException * @throws NonStackableItemsServiceException
* if the item could not be splitted * if the item could not be splitted
* @throws CharacterInventoryItemDoesNotExistException
* if the character's inventory does not contain the requested
* item
*/ */
Item drop(Item item, long count, Point3D point, Actor actor) Item drop(Item item, long count, Point3D point, Actor actor)
throws ItemAlreadyOnGroundServiceException, throws ItemAlreadyOnGroundServiceException,
AlreadySpawnedServiceException, SpawnPointNotFoundServiceException, AlreadySpawnedServiceException, SpawnPointNotFoundServiceException,
NotEnoughItemsServiceException, NonStackableItemsServiceException; NotEnoughItemsServiceException, NonStackableItemsServiceException,
CharacterInventoryItemDoesNotExistException;
/** /**
* Drops an item on the ground. If <code>actor</code> is not * Drops an item on the ground. If <code>actor</code> is not
@@ -209,9 +234,12 @@ public interface ItemService extends Service {
* if <code>count</code> is bigger than {@link Item#getCount()}. * if <code>count</code> is bigger than {@link Item#getCount()}.
* @throws NonStackableItemsServiceException * @throws NonStackableItemsServiceException
* if the item could not be splitted * if the item could not be splitted
* @throws CharacterInventoryItemDoesNotExistException
* if the character's inventory does not have the requested item
*/ */
void drop(Item item, Point3D point, Actor actor) void drop(Item item, Point3D point, Actor actor)
throws ItemAlreadyOnGroundServiceException, throws ItemAlreadyOnGroundServiceException,
AlreadySpawnedServiceException, SpawnPointNotFoundServiceException, AlreadySpawnedServiceException, SpawnPointNotFoundServiceException,
NotEnoughItemsServiceException, NonStackableItemsServiceException; NotEnoughItemsServiceException, NonStackableItemsServiceException,
CharacterInventoryItemDoesNotExistException;
} }

View File

@@ -40,6 +40,9 @@ import com.l2jserver.service.ServiceStopException;
import com.l2jserver.service.core.threading.AsyncFuture; import com.l2jserver.service.core.threading.AsyncFuture;
import com.l2jserver.service.database.DatabaseService; import com.l2jserver.service.database.DatabaseService;
import com.l2jserver.service.game.character.CharacterAction; import com.l2jserver.service.game.character.CharacterAction;
import com.l2jserver.service.game.character.CharacterInventoryItemDoesNotExistException;
import com.l2jserver.service.game.character.CharacterInventoryItemExistsException;
import com.l2jserver.service.game.character.CharacterInventoryService;
import com.l2jserver.service.game.spawn.AlreadySpawnedServiceException; import com.l2jserver.service.game.spawn.AlreadySpawnedServiceException;
import com.l2jserver.service.game.spawn.NotSpawnedServiceException; import com.l2jserver.service.game.spawn.NotSpawnedServiceException;
import com.l2jserver.service.game.spawn.SpawnPointNotFoundServiceException; import com.l2jserver.service.game.spawn.SpawnPointNotFoundServiceException;
@@ -68,6 +71,11 @@ public class ItemServiceImpl extends
* The {@link WorldService} event dispatcher * The {@link WorldService} event dispatcher
*/ */
private final WorldEventDispatcherService eventDispatcher; private final WorldEventDispatcherService eventDispatcher;
/**
* The {@link L2Character} inventory service
*/
private final CharacterInventoryService inventoryService;
/** /**
* The {@link ItemID} provider * The {@link ItemID} provider
*/ */
@@ -85,17 +93,21 @@ public class ItemServiceImpl extends
* the spawn service * the spawn service
* @param eventDispatcher * @param eventDispatcher
* the world service event dispatcher * the world service event dispatcher
* @param inventoryService
* the character inventory service
* @param itemIdProvider * @param itemIdProvider
* the {@link ItemID} provider * the {@link ItemID} provider
*/ */
@Inject @Inject
private ItemServiceImpl(ItemDAO itemDao, SpawnService spawnService, private ItemServiceImpl(ItemDAO itemDao, SpawnService spawnService,
WorldEventDispatcherService eventDispatcher, WorldEventDispatcherService eventDispatcher,
CharacterInventoryService inventoryService,
ItemIDProvider itemIdProvider) { ItemIDProvider itemIdProvider) {
super(ItemServiceConfiguration.class); super(ItemServiceConfiguration.class);
this.itemDao = itemDao; this.itemDao = itemDao;
this.spawnService = spawnService; this.spawnService = spawnService;
this.eventDispatcher = eventDispatcher; this.eventDispatcher = eventDispatcher;
this.inventoryService = inventoryService;
this.itemIdProvider = itemIdProvider; this.itemIdProvider = itemIdProvider;
} }
@@ -137,7 +149,7 @@ public class ItemServiceImpl extends
@Override @Override
public Item action(Item item, L2Character character, CharacterAction action) public Item action(Item item, L2Character character, CharacterAction action)
throws ItemNotOnGroundServiceException, NotSpawnedServiceException { throws ItemNotOnGroundServiceException, NotSpawnedServiceException, CharacterInventoryItemExistsException, CharacterInventoryItemDoesNotExistException {
switch (action) { switch (action) {
case CLICK: case CLICK:
return pickUp(item, character); return pickUp(item, character);
@@ -189,12 +201,12 @@ public class ItemServiceImpl extends
@Override @Override
public boolean destroy(Item item, long count) public boolean destroy(Item item, long count)
throws NotEnoughItemsServiceException, throws NotEnoughItemsServiceException,
NonStackableItemsServiceException { NonStackableItemsServiceException, CharacterInventoryItemDoesNotExistException {
synchronized (item) { synchronized (item) {
Item destroyItem = split(item, count); Item destroyItem = split(item, count);
itemDao.deleteObjectsAsync(destroyItem); itemDao.deleteObjectsAsync(destroyItem);
if (destroyItem.getOwnerID() != null) if (destroyItem.getOwnerID() != null)
destroyItem.getOwner().getInventory().remove(destroyItem); inventoryService.remove(destroyItem.getOwner(), destroyItem);
if (!destroyItem.equals(item)) if (!destroyItem.equals(item))
itemDao.saveObjectsAsync(item); itemDao.saveObjectsAsync(item);
return destroyItem.equals(item); return destroyItem.equals(item);
@@ -202,12 +214,12 @@ public class ItemServiceImpl extends
} }
@Override @Override
public void destroy(Item... items) { public void destroy(Item... items) throws CharacterInventoryItemDoesNotExistException {
// requests the delete and starts removing items from inventory model // requests the delete and starts removing items from inventory model
AsyncFuture<Integer> async = itemDao.deleteObjectsAsync(items); AsyncFuture<Integer> async = itemDao.deleteObjectsAsync(items);
for (final Item item : items) { for (final Item item : items) {
if (item.getOwnerID() != null) { if (item.getOwnerID() != null) {
item.getOwner().getInventory().remove(item); inventoryService.remove(item.getOwner(), item);
} }
} }
// now wait until database operation finishes // now wait until database operation finishes
@@ -216,7 +228,7 @@ public class ItemServiceImpl extends
@Override @Override
public Item pickUp(Item item, L2Character character) public Item pickUp(Item item, L2Character character)
throws ItemNotOnGroundServiceException, NotSpawnedServiceException { throws ItemNotOnGroundServiceException, NotSpawnedServiceException, CharacterInventoryItemExistsException, CharacterInventoryItemDoesNotExistException {
synchronized (item) { synchronized (item) {
if (item.getLocation() != ItemLocation.GROUND) if (item.getLocation() != ItemLocation.GROUND)
throw new ItemNotOnGroundServiceException(); throw new ItemNotOnGroundServiceException();
@@ -236,15 +248,15 @@ public class ItemServiceImpl extends
Item[] deleteItems = ArrayUtils.copyArrayExcept(stackItems, Item[] deleteItems = ArrayUtils.copyArrayExcept(stackItems,
item); item);
destroy(deleteItems); destroy(deleteItems);
character.getInventory().add(item); inventoryService.add(character, item);
} catch (NonStackableItemsServiceException e) { } catch (NonStackableItemsServiceException e) {
character.getInventory().add(item); inventoryService.add(character, item);
} }
} else { } else {
character.getInventory().add(item); inventoryService.add(character, item);
} }
character.getInventory().add(item); // character.getInventory().add(item);
this.items.remove(item); this.items.remove(item);
// removes transient state // removes transient state
@@ -269,7 +281,7 @@ public class ItemServiceImpl extends
throws SpawnPointNotFoundServiceException, throws SpawnPointNotFoundServiceException,
ItemAlreadyOnGroundServiceException, ItemAlreadyOnGroundServiceException,
AlreadySpawnedServiceException, NotEnoughItemsServiceException, AlreadySpawnedServiceException, NotEnoughItemsServiceException,
NonStackableItemsServiceException { NonStackableItemsServiceException, CharacterInventoryItemDoesNotExistException {
synchronized (item) { synchronized (item) {
if (item.getLocation() == ItemLocation.GROUND) if (item.getLocation() == ItemLocation.GROUND)
throw new AlreadySpawnedServiceException(); throw new AlreadySpawnedServiceException();
@@ -285,7 +297,7 @@ public class ItemServiceImpl extends
if (actor instanceof L2Character) { if (actor instanceof L2Character) {
if (sourceItem.equals(item)) { if (sourceItem.equals(item)) {
((L2Character) actor).getInventory().remove(item); inventoryService.remove(((L2Character) actor), item);
} }
} }
@@ -324,7 +336,7 @@ public class ItemServiceImpl extends
throws SpawnPointNotFoundServiceException, throws SpawnPointNotFoundServiceException,
ItemAlreadyOnGroundServiceException, ItemAlreadyOnGroundServiceException,
AlreadySpawnedServiceException, NotEnoughItemsServiceException, AlreadySpawnedServiceException, NotEnoughItemsServiceException,
NonStackableItemsServiceException { NonStackableItemsServiceException, CharacterInventoryItemDoesNotExistException {
drop(item, item.getCount(), point, actor); drop(item, item.getCount(), point, actor);
} }

View File

@@ -0,0 +1,211 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.service.network;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelFutureListener;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.ServerChannel;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
import org.jboss.netty.logging.InternalLoggerFactory;
import org.jboss.netty.logging.Slf4JLoggerFactory;
import org.jboss.netty.util.ThreadNameDeterminer;
import org.jboss.netty.util.ThreadRenamingRunnable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Preconditions;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.l2jserver.model.id.object.CharacterID;
import com.l2jserver.service.AbstractConfigurableService;
import com.l2jserver.service.AbstractService.Depends;
import com.l2jserver.service.core.logging.LoggingService;
import com.l2jserver.service.core.threading.ThreadPool;
import com.l2jserver.service.core.threading.ThreadPoolPriority;
import com.l2jserver.service.core.threading.ThreadService;
import com.l2jserver.service.game.world.WorldService;
import com.l2jserver.service.network.keygen.BlowfishKeygenService;
import com.l2jserver.service.network.model.Lineage2Client;
import com.l2jserver.service.network.model.packet.ServerPacket;
import com.l2jserver.util.ThreadPoolUtils;
import com.l2jserver.util.factory.CollectionFactory;
/**
* Netty network service implementation
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
@Depends({ LoggingService.class, ThreadService.class,
BlowfishKeygenService.class, WorldService.class })
public abstract class AbstractNettyNetworkService extends
AbstractConfigurableService<NetworkServiceConfiguration> implements
NetworkService {
/**
* The logger
*/
private final Logger log = LoggerFactory.getLogger(this.getClass());
/**
* The {@link ThreadService}
*/
private final ThreadService threadService;
/**
* The Google Guice {@link Injector}
*/
private final Injector injector;
/**
* Netty Boss {@link ThreadPool}
*/
private ThreadPool bossPool;
/**
* Netty Worker {@link ThreadPool}
*/
private ThreadPool workerPool;
/**
* The server bootstrap
*/
private ServerBootstrap server;
/**
* The server channel
*/
private ServerChannel channel;
/**
* The client list. This list all active clients in the server
*/
private Set<Lineage2Client> clients = CollectionFactory.newSet();
/**
* @param injector
* the {@link Guice} {@link Injector}
* @param threadService
* the {@link ThreadService}
*/
@Inject
public AbstractNettyNetworkService(Injector injector, ThreadService threadService) {
super(NetworkServiceConfiguration.class);
this.threadService = threadService;
this.injector = injector;
InternalLoggerFactory.setDefaultFactory(new Slf4JLoggerFactory());
}
@Override
protected void doStart() {
bossPool = threadService.createThreadPool("netty-boss", 10, 60,
TimeUnit.SECONDS, ThreadPoolPriority.HIGH);
workerPool = threadService.createThreadPool("netty-worker", 50, 60,
TimeUnit.SECONDS, ThreadPoolPriority.HIGH);
ThreadRenamingRunnable
.setThreadNameDeterminer(new ThreadNameDeterminer() {
@Override
public String determineThreadName(String currentThreadName,
String proposedThreadName) throws Exception {
return currentThreadName;
}
});
server = new ServerBootstrap(new NioServerSocketChannelFactory(
ThreadPoolUtils.wrap(bossPool),
ThreadPoolUtils.wrap(workerPool), 50));
server.setPipelineFactory(createPipelineFactory(injector));
channel = (ServerChannel) server.bind(config.getListenAddress());
}
/**
* Simple factory method that creates a new {@link ChannelPipelineFactory}
* @param injector the injector instance
* @return the newly created channel pipeline factory
*/
protected abstract ChannelPipelineFactory createPipelineFactory(Injector injector);
@Override
public void register(final Lineage2Client client) {
Preconditions.checkNotNull(client, "client");
log.debug("Registering client: {}", client);
clients.add(client);
client.getChannel().getCloseFuture()
.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future)
throws Exception {
unregister(client);
}
});
}
@Override
public void unregister(Lineage2Client client) {
Preconditions.checkNotNull(client, "client");
log.debug("Unregistering client: {}", client);
clients.remove(client);
}
@Override
public Lineage2Client discover(CharacterID character) {
Preconditions.checkNotNull(character, "character");
log.debug("Discovering client object for {}", character);
for (final Lineage2Client client : clients) {
if (character.equals(client.getCharacterID()))
return client;
}
return null;
}
@Override
public void broadcast(ServerPacket packet) {
Preconditions.checkNotNull(packet, "packet");
log.debug("Broadcasting {} packet to all connected clients", packet);
channel.write(packet);
}
@Override
public void cleanup() {
// TODO
}
@Override
protected void doStop() {
try {
channel.close().awaitUninterruptibly();
server.releaseExternalResources();
bossPool.dispose();
workerPool.dispose();
} finally {
server = null;
channel = null;
bossPool = null;
workerPool = null;
}
clients.clear();
}
}

View File

@@ -67,6 +67,22 @@ public interface Lineage2Client {
*/ */
void setSession(Lineage2Session session); void setSession(Lineage2Session session);
/**
* Enables the client decryptor network filter
*
* @param key
* the key
*/
void enableDecrypter(Lineage2CryptographyKey key);
/**
* Enables the client encryptor network filter
*
* @param key
* the key
*/
void enableEncrypter(Lineage2CryptographyKey key);
/** /**
* @return the version * @return the version
*/ */
@@ -89,6 +105,19 @@ public interface Lineage2Client {
*/ */
boolean supports(ProtocolVersion version); boolean supports(ProtocolVersion version);
/**
* Check if the client supports an given version of the protocol. Note that
* if the protocol is not known false will always be returned.
*
* @param from
* the minimum protocol version to test for support
* @param to
* the maximum protocol version to test for support
* @return true if version is supported by the client
* @see ProtocolVersion#supports(ProtocolVersion)
*/
boolean supports(ProtocolVersion from, ProtocolVersion to);
/** /**
* Get the channel * Get the channel
* *

View File

@@ -1,419 +0,0 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFuture;
import com.l2jserver.game.net.codec.Lineage2Decrypter;
import com.l2jserver.game.net.codec.Lineage2Encrypter;
import com.l2jserver.game.net.codec.Lineage2PacketReader;
import com.l2jserver.game.net.codec.Lineage2PacketWriter;
import com.l2jserver.game.net.packet.server.SM_ACTION_FAILED;
import com.l2jserver.game.net.packet.server.SM_CHAR_INVENTORY;
import com.l2jserver.game.net.packet.server.SM_CHAR_INVENTORY_UPDATE;
import com.l2jserver.game.net.packet.server.SM_CHAR_INVENTORY_UPDATE.InventoryUpdateType;
import com.l2jserver.game.net.packet.server.SM_COMMUNITY_HTML;
import com.l2jserver.game.net.packet.server.SM_HTML;
import com.l2jserver.game.net.packet.server.SM_SYSTEM_MESSAGE;
import com.l2jserver.model.game.Fort;
import com.l2jserver.model.game.Skill;
import com.l2jserver.model.id.object.CharacterID;
import com.l2jserver.model.template.ItemTemplate;
import com.l2jserver.model.world.Item;
import com.l2jserver.model.world.L2Character;
import com.l2jserver.service.network.model.Lineage2Client;
import com.l2jserver.service.network.model.Lineage2Session;
import com.l2jserver.service.network.model.ProtocolVersion;
import com.l2jserver.service.network.model.SystemMessage;
import com.l2jserver.service.network.model.packet.ServerPacket;
import com.l2jserver.util.html.markup.HtmlTemplate;
/**
* This object connects the model (structure objects normally stored in the
* database) to the controller (protocol stuff).
* <p>
* This class also provides handy methods for {@link #write(ServerPacket)
* writing} packets.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class FreyaLineage2Client implements Lineage2Client {
/**
* The connection channel
*/
private final Channel channel;
/**
* The character object
*/
private CharacterID characterID;
/**
* The Lineage 2 session
*/
private Lineage2Session session;
/**
* The client supported protocol version
*/
private ProtocolVersion version;
/**
* Creates a new instance
*
* @param channel
* the channel
*/
public FreyaLineage2Client(Channel channel) {
this.channel = channel;
}
/**
* @return the character
*/
public boolean hasCharacter() {
return characterID != null;
}
/**
* @return the character ID
*/
public CharacterID getCharacterID() {
return characterID;
}
/**
* @return the character
*/
public L2Character getCharacter() {
return characterID.getObject();
}
/**
* @param characterID
* the character ID to set
*/
public void setCharacterID(CharacterID characterID) {
this.characterID = characterID;
}
/**
* @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;
}
/**
* @return the version
*/
public ProtocolVersion getVersion() {
return version;
}
/**
* @param version
* the version to set
*/
public void setVersion(ProtocolVersion version) {
this.version = version;
}
/**
* Check if the client supports an given version of the protocol. Note that
* if the protocol is not known false will always be returned.
*
* @param version
* the protocol version to test for support
* @return true if version is supported by the client
* @see ProtocolVersion#supports(ProtocolVersion)
*/
public boolean supports(ProtocolVersion version) {
if (version == null)
return false;
return this.version.supports(version);
}
/**
* Get the channel
*
* @return the channel
*/
public Channel getChannel() {
return channel;
}
/**
* Test if the client is still open.
* <p>
* Please note that the channel can be open but disconnected!
*
* @return true if the client is still open
* @see Channel#isOpen()
*/
public boolean isOpen() {
return channel.isOpen();
}
/**
* Test if the client is still connected
* <p>
* Please note that the channel can be open but disconnected!
*
* @return true if the client is still connected
* @see Channel#isConnected()
*/
public boolean isConnected() {
return channel.isConnected();
}
/**
* Writes an packet to this client
* <p>
* Please note that this method will <b>not</b> block for the packets to be
* sent. It is possible to check if the packet was sent successfully using
* the {@link ChannelFuture}.
*
* @param packet
* the packet
* @return the {@link ChannelFuture} that will be notified once the packet
* has been written.
*/
public ChannelFuture write(ServerPacket packet) {
return channel.write(packet);
}
/**
* Sends a string message to this client
*
* @param message
* the message
* @return the {@link ChannelFuture} that will be notified once the packet
* has been written.
*/
public ChannelFuture sendMessage(String message) {
return write(new SM_SYSTEM_MESSAGE(SystemMessage.S1).addString(message));
}
/**
* Sends a {@link SystemMessage} to this client
*
* @param message
* the {@link SystemMessage}
* @return the {@link ChannelFuture} that will be notified once the packet
* has been written.
*/
public ChannelFuture sendSystemMessage(SystemMessage message) {
return write(new SM_SYSTEM_MESSAGE(message));
}
/**
* Sends a {@link SystemMessage} to this client
*
* @param message
* the {@link SystemMessage}
* @param args
* the arguments of the message, they will be automatically
* detected and inserted. See {@link SM_SYSTEM_MESSAGE} for more
* about supported formats.
* @return the {@link ChannelFuture} that will be notified once the packet
* has been written.
* @see SM_SYSTEM_MESSAGE
*/
public ChannelFuture sendSystemMessage(SystemMessage message,
Object... args) {
final SM_SYSTEM_MESSAGE packet = new SM_SYSTEM_MESSAGE(message);
for (final Object obj : args) {
if (obj instanceof String)
packet.addString((String) obj);
else if (obj instanceof ItemTemplate)
packet.addItem((ItemTemplate) obj);
else if (obj instanceof Item)
packet.addItem((Item) obj);
else if (obj instanceof Number)
packet.addNumber((Integer) obj);
else if (obj instanceof Skill)
packet.addSkill((Skill) obj);
else if (obj instanceof Fort)
packet.addFort((Fort) obj);
}
return write(packet);
}
/**
* Sends a {@link SM_ACTION_FAILED} to the client.
* <p>
* This is an convenience method for <blockquote><code>
* conn.write(ActionFailedPacket.SHARED_INSTANCE);</code></blockquote>
*
* @return the {@link ChannelFuture} that will be notified once the packet
* has been written.
*/
public ChannelFuture sendActionFailed() {
return write(SM_ACTION_FAILED.SHARED_INSTANCE);
}
/**
* Sends a {@link SM_HTML} packet to the client. In the packet, the NPC will
* be null. If you wish to send the HTML with an NPC, you should send the
* packet directly.
* <p>
* This is an convenience method for <blockquote><code>
* conn.write(new SM_HTML(null, template));</code></blockquote>
*
* @param template
* the HTML template to be sent
* @return the {@link ChannelFuture} that will be notified once the packet
* has been written.
*/
public ChannelFuture sendHTML(HtmlTemplate template) {
return write(new SM_HTML(null, template));
}
/**
* Sends a {@link SM_COMMUNITY_HTML} packet to the client. HTML code is not
* displayed in the regular chat window, they will appear in a large one.
* <p>
* This is an convenience method for <blockquote><code>
* conn.write(new SM_COMMUNITY_HTML(template));</code></blockquote>
*
* @param template
* the HTML template to be sent
* @return the {@link ChannelFuture} that will be notified once the packet
* has been written.
*/
public ChannelFuture sendCommunityHTML(HtmlTemplate template) {
return write(new SM_COMMUNITY_HTML(template));
}
/**
* Sends the whole user inventory to the client. This is a very bandwidth
* consuming process and should be avoided.
*
* @return the {@link ChannelFuture} that will be notified once the packet
* has been written.
*/
public ChannelFuture updateEntireInventoryItems() {
return write(new SM_CHAR_INVENTORY(characterID.getObject()
.getInventory()));
}
/**
* Removes <code>items</code> from the game client UI.
*
* @param items
* the list of items to be removed
* @return the {@link ChannelFuture} that will be notified once the packet
* has been written.
*/
public ChannelFuture removeInventoryItems(Item... items) {
return write(new SM_CHAR_INVENTORY_UPDATE(InventoryUpdateType.REMOVE,
items));
}
/**
* Updates <code>items</code> in the game client UI.
*
* @param items
* the list of items to be updated
* @return the {@link ChannelFuture} that will be notified once the packet
* has been written.
*/
public ChannelFuture updateInventoryItems(Item... items) {
return write(new SM_CHAR_INVENTORY_UPDATE(InventoryUpdateType.UPDATE,
items));
}
/**
* Adds <code>items</code> in the game client UI.
*
* @param items
* the list of items to be added
* @return the {@link ChannelFuture} that will be notified once the packet
* has been written.
*/
public ChannelFuture addInventoryItems(Item... items) {
return write(new SM_CHAR_INVENTORY_UPDATE(InventoryUpdateType.ADD,
items));
}
/**
* Disconnects this client, without closing the channel.
*
* @return the {@link ChannelFuture}
*/
public ChannelFuture disconnect() {
return channel.disconnect();
}
/**
* Closes the channel of this client.
*
* @return the {@link ChannelFuture}
*/
public ChannelFuture close() {
return channel.close();
}
/**
* @return the client {@link Lineage2Decrypter}
*/
public Lineage2Decrypter getDecrypter() {
return (Lineage2Decrypter) channel.getPipeline().get(
Lineage2Decrypter.HANDLER_NAME);
}
/**
* @return the client {@link Lineage2Encrypter}
*/
public Lineage2Encrypter getEncrypter() {
return (Lineage2Encrypter) channel.getPipeline().get(
Lineage2Encrypter.HANDLER_NAME);
}
/**
* @return the client {@link Lineage2PacketReader}
*/
public Lineage2PacketReader getPacketReader() {
return (Lineage2PacketReader) channel.getPipeline().get(
Lineage2PacketReader.HANDLER_NAME);
}
/**
* @return the client {@link Lineage2PacketWriter}
*/
public Lineage2PacketWriter getPacketWriter() {
return (Lineage2PacketWriter) channel.getPipeline().get(
Lineage2PacketWriter.HANDLER_NAME);
}
@Override
public String toString() {
return "Lineage2Client [channel=" + channel + ", characterID="
+ characterID + ", session=" + session + ", version=" + version
+ "]";
}
}

View File

@@ -34,7 +34,7 @@ import com.l2jserver.game.net.codec.Lineage2PacketReader;
import com.l2jserver.game.net.codec.Lineage2PacketWriter; import com.l2jserver.game.net.codec.Lineage2PacketWriter;
import com.l2jserver.game.net.handler.Lineage2PacketHandler; import com.l2jserver.game.net.handler.Lineage2PacketHandler;
import com.l2jserver.game.net.handler.Lineage2TimeoutHandler; import com.l2jserver.game.net.handler.Lineage2TimeoutHandler;
import com.l2jserver.service.network.NettyNetworkService; import com.l2jserver.service.network.AbstractNettyNetworkService;
import com.l2jserver.service.network.NetworkService; import com.l2jserver.service.network.NetworkService;
/** /**
@@ -49,9 +49,9 @@ public class Lineage2PipelineFactory implements ChannelPipelineFactory {
*/ */
private final Injector injector; private final Injector injector;
/** /**
* The {@link NettyNetworkService} * The {@link AbstractNettyNetworkService}
*/ */
private final NettyNetworkService nettyNetworkService; private final AbstractNettyNetworkService nettyNetworkService;
/** /**
* Creates a new instance of this pipeline * Creates a new instance of this pipeline
@@ -65,7 +65,7 @@ public class Lineage2PipelineFactory implements ChannelPipelineFactory {
public Lineage2PipelineFactory(Injector injector, public Lineage2PipelineFactory(Injector injector,
NetworkService networkService) { NetworkService networkService) {
this.injector = injector; this.injector = injector;
this.nettyNetworkService = (NettyNetworkService) networkService; this.nettyNetworkService = (AbstractNettyNetworkService) networkService;
} }
@Override @Override

View File

@@ -1,205 +0,0 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.client;
import org.jboss.netty.buffer.ChannelBuffer;
import com.google.inject.Inject;
import com.l2jserver.model.world.L2Character;
import com.l2jserver.model.world.L2Character.CharacterMoveType;
import com.l2jserver.service.game.character.CharacterAlreadyRunningServiceException;
import com.l2jserver.service.game.character.CharacterAlreadyWalkingServiceException;
import com.l2jserver.service.game.character.CharacterService;
import com.l2jserver.service.network.model.Lineage2Client;
import com.l2jserver.service.network.model.packet.AbstractClientPacket;
/**
* This packet notifies the server which character the player has chosen to use.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class CM_ACTION_USE extends AbstractClientPacket {
/**
* The packet OPCODE
*/
public static final int OPCODE = 0x56;
/**
* The {@link CharacterService}
*/
private final CharacterService charService;
/**
* The action to be performed
*/
private Action action;
/**
* The enumeration of all possible actions
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public enum Action {
/**
* Toggles the character in SIT or STAND mode
*/
SIT_STAND(0),
/**
* Toggles the character in WALK or RUN mode
*/
WALK_RUN(1),
/**
* Stats a new private store sell
*/
PRIVATE_STORE_SELL(10),
/**
* Stats a new private store buy
*/
PRIVATE_STORE_BUY(11),
/**
* Sets the pet in follow mode
*/
PET_FOLLOW_MOVE(15),
/**
* Sets the pet in follow mode 2
*/
PET_FOLLOW_MOVE2(21),
/**
* Orders the pet to attack
*/
PET_ATTACK(16),
/**
* Orders the pet to attack (second type)
*/
PET_ATTACK2(22),
/**
* Orders the pet to stop
*/
PET_STOP(17),
/**
* Orders the pet to stop (second type)
*/
PET_STOP2(23),
/**
* Unsummons the pet
*/
PET_UNSUMMON(19),
/**
* Mounts or dismount from pet
*/
MOUNT_DISMOUNT(38),
/**
* Switch Wild Hog Cannon mode
*/
WILD_HOG_CANNON_SWITCH_MODE(32),
/**
* Stops Wild Hog Cannon
*/
WILD_HOG_CANNON_STOP(41),
/**
* Souless toxic smoke
*/
SOULESS_TOXIC_SMOKE(36),
/**
* Souless parasite burst
*/
SOULESS_PARASITE_BURST(39),
/**
* Creates a new darwven manufacture
*/
DWARVEN_MANUFACTURE(37);
/**
* The numeric action id
*/
public final int id;
/**
* @param id
* the numeric action id
*/
Action(int id) {
this.id = id;
}
/**
* Resolves the numeric id into an Java type action
*
* @param id
* the numeric id
* @return the resolved action
*/
public static Action fromID(int id) {
for (final Action action : values())
if (action.id == id)
return action;
return null;
}
}
/**
* If CTRL key was pressed for this action
*/
@SuppressWarnings("unused")
private boolean ctrlPressed;
/**
* If SHIFT key was pressed for this action
*/
@SuppressWarnings("unused")
private boolean shiftPressed;
/**
* @param charService
* the character service
*/
@Inject
public CM_ACTION_USE(CharacterService charService) {
this.charService = charService;
}
@Override
public void read(Lineage2Client conn, ChannelBuffer buffer) {
action = Action.fromID(buffer.readInt());
ctrlPressed = (buffer.readByte() == 1 ? true : false);
shiftPressed = (buffer.readByte() == 1 ? true : false);
}
@Override
public void process(final Lineage2Client conn) {
final L2Character character = conn.getCharacter();
switch (action) {
case SIT_STAND:
// TODO
break;
case WALK_RUN:
try {
if (character.getMoveType() == CharacterMoveType.WALK) {
charService.run(character);
} else {
charService.walk(character);
}
} catch (CharacterAlreadyWalkingServiceException e) {
conn.sendActionFailed();
} catch (CharacterAlreadyRunningServiceException e) {
conn.sendActionFailed();
}
break;
}
}
}

View File

@@ -1,92 +0,0 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.client;
import org.jboss.netty.buffer.ChannelBuffer;
import com.google.inject.Inject;
import com.l2jserver.service.ServiceException;
import com.l2jserver.service.game.admin.AdministratorService;
import com.l2jserver.service.network.model.Lineage2Client;
import com.l2jserver.service.network.model.packet.AbstractClientPacket;
import com.l2jserver.util.BufferUtils;
/**
* Executes an administrator action
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class CM_ADMIN_COMMAND extends AbstractClientPacket {
/**
* The packet OPCODE
*/
public static final int OPCODE = 0x74;
/**
* The admin service
*/
private final AdministratorService adminService;
/**
* The command
*/
@SuppressWarnings("unused")
private String command;
/**
* @param adminService
* the administrator service
*/
@Inject
public CM_ADMIN_COMMAND(AdministratorService adminService) {
this.adminService = adminService;
}
@Override
public void read(Lineage2Client conn, ChannelBuffer buffer) {
command = BufferUtils.readString(buffer).trim();
}
@Override
public void process(final Lineage2Client conn) {
// final StringTokenizer tokenizer = new StringTokenizer(command, " ");
// final String cmd = tokenizer.nextToken();
// if (cmd.equals("tele")) {
// Coordinate coord = Coordinate.fromXYZ(
// Integer.parseInt(tokenizer.nextToken()),
// Integer.parseInt(tokenizer.nextToken()),
// Integer.parseInt(tokenizer.nextToken()));
// try {
// spawnService.teleport(conn.getCharacter(), coord);
// } catch (NotSpawnedServiceException e) {
// conn.sendActionFailed();
// } catch (CharacterAlreadyTeleportingServiceException e) {
// conn.sendActionFailed();
// }
// }
try {
adminService
.command(conn, conn.getCharacter(), "", new String[] {});
} catch (ServiceException e) {
conn.sendMessage("Invalid administrator command or syntax");
} finally {
conn.sendActionFailed();
}
// TODO implement admin commands
}
}

View File

@@ -1,145 +0,0 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
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.game.net.packet.server.SM_CHAR_LIST;
import com.l2jserver.model.dao.CharacterDAO;
import com.l2jserver.model.id.AccountID;
import com.l2jserver.model.id.provider.AccountIDProvider;
import com.l2jserver.model.world.L2Character;
import com.l2jserver.service.network.model.Lineage2Client;
import com.l2jserver.service.network.model.Lineage2Session;
import com.l2jserver.service.network.model.packet.AbstractClientPacket;
import com.l2jserver.util.BufferUtils;
/**
* 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 CM_AUTH_LOGIN extends AbstractClientPacket {
/**
* The packet OPCODE
*/
public static final int OPCODE = 0x2b;
/**
* The {@link CharacterDAO} implementation
*/
private final CharacterDAO characterDao;
/**
* The {@link AccountID} factory
*/
private final AccountIDProvider accountIdFactory;
// packet
/**
* User account name
*/
private String loginName;
/**
* The play key 1
*/
private int playKey1;
/**
* The play key 2
*/
private int playKey2;
/**
* The login key 1
*/
private int loginKey1;
/**
* The login key 2
*/
private int loginKey2;
/**
* @param characterDao
* the character DAO
* @param accountIdFactory
* the account id factory
*/
@Inject
public CM_AUTH_LOGIN(CharacterDAO characterDao,
AccountIDProvider accountIdFactory) {
this.characterDao = characterDao;
this.accountIdFactory = accountIdFactory;
}
@Override
public void read(Lineage2Client conn, ChannelBuffer buffer) {
this.loginName = BufferUtils.readString(buffer).toLowerCase();
this.playKey1 = buffer.readInt();
this.playKey2 = buffer.readInt();
this.loginKey1 = buffer.readInt();
this.loginKey2 = buffer.readInt();
}
@Override
public void process(final Lineage2Client conn) {
final AccountID accountId = accountIdFactory.resolveID(loginName);
conn.setSession(new Lineage2Session(accountId, playKey1, playKey2,
loginKey1, loginKey2));
final List<L2Character> chars = characterDao.selectByAccount(accountId);
conn.write(SM_CHAR_LIST.fromL2Session(conn.getSession(),
chars.toArray(new L2Character[chars.size()])));
}
/**
* @return the loginName
*/
public String getLoginName() {
return loginName;
}
/**
* @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;
}
}

View File

@@ -1,135 +0,0 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.client;
import java.util.StringTokenizer;
import org.jboss.netty.buffer.ChannelBuffer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.inject.Inject;
import com.l2jserver.model.id.ObjectID;
import com.l2jserver.model.id.object.NPCID;
import com.l2jserver.model.id.object.provider.ObjectIDResolver;
import com.l2jserver.model.world.NPC;
import com.l2jserver.model.world.npc.NPCController.NPCControllerException;
import com.l2jserver.service.game.character.CannotSetTargetServiceException;
import com.l2jserver.service.game.npc.ActionServiceException;
import com.l2jserver.service.game.npc.NPCService;
import com.l2jserver.service.network.model.Lineage2Client;
import com.l2jserver.service.network.model.packet.AbstractClientPacket;
import com.l2jserver.util.BufferUtils;
/**
* Executes an bypass command
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class CM_BYPASS extends AbstractClientPacket {
/**
* The logger
*/
private final Logger log = LoggerFactory.getLogger(this.getClass());
/**
* The packet OPCODE
*/
public static final int OPCODE = 0x23;
/**
* The {@link ObjectID} resolver
*/
private final ObjectIDResolver idResolver;
/**
* The {@link NPC} service
*/
private final NPCService npcService;
/**
* The bypass command
*/
private String command;
/**
* @param idResolver
* the object id resolver
* @param npcService
* the {@link NPC} service
*/
@Inject
public CM_BYPASS(ObjectIDResolver idResolver, NPCService npcService) {
this.idResolver = idResolver;
this.npcService = npcService;
}
@Override
public void read(Lineage2Client conn, ChannelBuffer buffer) {
this.command = BufferUtils.readString(buffer);
}
@Override
public void process(final Lineage2Client conn) {
// parse command
final StringTokenizer tokenizer = new StringTokenizer(command, "_ ");
final String type = tokenizer.nextToken();
switch (type) {
case "npc":
final int objectId = Integer.parseInt(tokenizer.nextToken());
final ObjectID<NPC> id = idResolver.resolve(objectId);
if (!(id instanceof NPCID)) {
conn.sendActionFailed();
return;
}
final NPC npc = id.getObject();
try {
npcService.action(npc, conn.getCharacter(),
createArgumentArray(tokenizer));
} catch (ActionServiceException e) {
conn.sendActionFailed();
} catch (CannotSetTargetServiceException e) {
conn.sendActionFailed();
} catch (NPCControllerException e) {
if (e.getSystemMessage() != null)
conn.sendSystemMessage(e.getSystemMessage());
conn.sendActionFailed();
}
return;
default:
log.warn(
"Client {} requested an bypass not supported by server: {}",
conn, type);
return;
}
}
/**
* @param tokenizer
* the tokenizer
* @return an array of strings with each parameter
*/
private String[] createArgumentArray(StringTokenizer tokenizer) {
if (!tokenizer.hasMoreTokens())
return new String[0];
final String[] args = new String[tokenizer.countTokens()];
int i = 0;
while (tokenizer.hasMoreTokens()) {
args[i++] = tokenizer.nextToken();
}
return args;
}
}

View File

@@ -1,142 +0,0 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.client;
import org.jboss.netty.buffer.ChannelBuffer;
import com.google.inject.Inject;
import com.l2jserver.model.id.ObjectID;
import com.l2jserver.model.id.object.ItemID;
import com.l2jserver.model.id.object.NPCID;
import com.l2jserver.model.id.object.provider.ObjectIDResolver;
import com.l2jserver.model.world.Item;
import com.l2jserver.model.world.NPC;
import com.l2jserver.model.world.npc.NPCController.NPCControllerException;
import com.l2jserver.service.game.character.CannotSetTargetServiceException;
import com.l2jserver.service.game.character.CharacterAction;
import com.l2jserver.service.game.item.ItemNotOnGroundServiceException;
import com.l2jserver.service.game.item.ItemService;
import com.l2jserver.service.game.npc.ActionServiceException;
import com.l2jserver.service.game.npc.NPCService;
import com.l2jserver.service.game.spawn.NotSpawnedServiceException;
import com.l2jserver.service.network.model.Lineage2Client;
import com.l2jserver.service.network.model.SystemMessage;
import com.l2jserver.service.network.model.packet.AbstractClientPacket;
import com.l2jserver.util.geometry.Coordinate;
/**
* Executes an action from an character to an NPC
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class CM_CHAR_ACTION extends AbstractClientPacket {
/**
* The packet OPCODE
*/
public static final int OPCODE = 0x1f;
/**
* The {@link ObjectID} resolver
*/
private final ObjectIDResolver idResolver;
/**
* The {@link NPC} Service
*/
private final NPCService npcService;
/**
* The {@link Item} Service
*/
private final ItemService itemService;
/**
* The object id
*/
private int objectId;
/**
* The action origin
*/
@SuppressWarnings("unused")
private Coordinate origin;
/**
* The character action type (aka mouse button)
*/
private CharacterAction action;
/**
* @param idResolver
* the id resolver
* @param npcService
* the npc service
* @param itemService
* the item service
*/
@Inject
public CM_CHAR_ACTION(ObjectIDResolver idResolver, NPCService npcService,
ItemService itemService) {
this.idResolver = idResolver;
this.npcService = npcService;
this.itemService = itemService;
}
@Override
public void read(Lineage2Client conn, ChannelBuffer buffer) {
this.objectId = buffer.readInt();
this.origin = Coordinate.fromXYZ(buffer.readInt(), buffer.readInt(),
buffer.readInt());
this.action = CharacterAction.fromID(buffer.readByte());
}
@Override
public void process(final Lineage2Client conn) {
final ObjectID<?> id = idResolver.resolve(objectId);
if (id instanceof NPCID) {
final NPC npc = ((NPCID) id).getObject();
try {
npcService.action(npc, conn.getCharacter(), action);
} catch (NPCControllerException e) {
if (e.getSystemMessage() != null)
conn.sendSystemMessage(e.getSystemMessage());
conn.sendActionFailed();
} catch (ActionServiceException | CannotSetTargetServiceException e) {
conn.sendActionFailed();
}
} else if (id instanceof ItemID) {
final Item item = ((ItemID) id).getObject();
try {
final Item stackItem = itemService.action(item,
conn.getCharacter(), action);
if (stackItem.equals(item)) { // adds
conn.addInventoryItems(stackItem);
} else { // update only
conn.updateInventoryItems(stackItem);
}
conn.sendSystemMessage(SystemMessage.YOU_PICKED_UP_S2_S1, Long
.toString(item.getCount()), item.getTemplate()
.getName());
conn.sendActionFailed();
} catch (ItemNotOnGroundServiceException
| NotSpawnedServiceException e) {
conn.sendSystemMessage(SystemMessage.FAILED_TO_PICKUP_S1, item
.getTemplate().getName());
conn.sendActionFailed();
}
} else {
conn.sendActionFailed();
return;
}
}
}

View File

@@ -1,65 +0,0 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.client;
import org.jboss.netty.buffer.ChannelBuffer;
import com.google.inject.Inject;
import com.l2jserver.service.game.spawn.CharacterNotTeleportingServiceException;
import com.l2jserver.service.game.spawn.SpawnService;
import com.l2jserver.service.network.model.Lineage2Client;
import com.l2jserver.service.network.model.packet.AbstractClientPacket;
/**
* Completes the creation of an character. Creates the object, inserts into the
* database and notifies the client about the status of the operation.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class CM_CHAR_APPEARING extends AbstractClientPacket {
/**
* The packet OPCODE
*/
public static final int OPCODE = 0x3a;
/**
* The {@link SpawnService}
*/
private final SpawnService spawnService;
/**
* @param spawnService
* the spawn service
*/
@Inject
public CM_CHAR_APPEARING(SpawnService spawnService) {
this.spawnService = spawnService;
}
@Override
public void read(Lineage2Client conn, ChannelBuffer buffer) {
}
@Override
public void process(final Lineage2Client conn) {
try {
spawnService.finishTeleport(conn.getCharacter());
} catch (CharacterNotTeleportingServiceException e) {
conn.sendActionFailed();
}
}
}

View File

@@ -1,166 +0,0 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
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.packet.server.SM_ACTION_FAILED;
import com.l2jserver.model.id.ObjectID;
import com.l2jserver.model.id.object.ActorID;
import com.l2jserver.model.id.object.provider.ObjectIDResolver;
import com.l2jserver.model.world.Actor;
import com.l2jserver.model.world.L2Character;
import com.l2jserver.service.game.character.ActorIsNotAttackableServiceException;
import com.l2jserver.service.game.character.CannotSetTargetServiceException;
import com.l2jserver.service.game.character.CharacterService;
import com.l2jserver.service.game.npc.NotAttackableNPCServiceException;
import com.l2jserver.service.network.model.Lineage2Client;
import com.l2jserver.service.network.model.packet.AbstractClientPacket;
import com.l2jserver.util.geometry.Coordinate;
/**
* Completes the creation of an character. Creates the object, inserts into the
* database and notifies the client about the status of the operation.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class CM_CHAR_ATTACK extends AbstractClientPacket {
/**
* The packet OPCODE
*/
public static final int OPCODE = 0x01;
/**
* The Logger
*/
private final Logger log = LoggerFactory.getLogger(this.getClass());
/**
* The {@link CharacterService}
*/
private final CharacterService charService;
/**
* The {@link ObjectID} resolver
*/
private final ObjectIDResolver idResolver;
/**
* The {@link ObjectID} being attacked
*/
private int objectId;
/**
* The position of the target
*/
@SuppressWarnings("unused")
private Coordinate origin;
/**
* The attack action type
*/
@SuppressWarnings("unused")
private CharacterAttackAction action;
/**
* Enumeration of all possible attack actions
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public enum CharacterAttackAction {
/**
* Normal click
*/
CLICK(0),
/**
* Clicked with shift-click
*/
SHIFT_CLICK(1);
/**
* The attack action numeric id
*/
public final int id;
/**
* @param id
* the action numeric id
*/
CharacterAttackAction(int id) {
this.id = id;
}
/**
* Resolves the numeric action id to an {@link CharacterAttackAction}
* type
*
* @param id
* the numeric id
* @return the resolved action
*/
public static CharacterAttackAction fromID(int id) {
for (final CharacterAttackAction action : values())
if (action.id == id)
return action;
return null;
}
}
/**
* @param charService
* the character service
* @param idResolver
* the object id resolver
*/
@Inject
public CM_CHAR_ATTACK(CharacterService charService,
ObjectIDResolver idResolver) {
this.charService = charService;
this.idResolver = idResolver;
}
@Override
public void read(Lineage2Client conn, ChannelBuffer buffer) {
this.objectId = buffer.readInt();
this.origin = Coordinate.fromXYZ(buffer.readInt(), buffer.readInt(),
buffer.readInt());
this.action = CharacterAttackAction.fromID(buffer.readByte());
}
@Override
public void process(final Lineage2Client conn) {
final L2Character character = conn.getCharacter();
// since this is an erasure type, this is safe.
final ObjectID<Actor> id = idResolver.resolve(objectId);
if (!(id instanceof ActorID)) {
conn.write(SM_ACTION_FAILED.SHARED_INSTANCE);
log.warn("Player {} is trying to attack {}, which is not an actor",
character, id);
return;
}
final Actor actor = id.getObject();
try {
charService.attack(character, actor);
} catch (CannotSetTargetServiceException e) {
conn.sendActionFailed();
} catch (ActorIsNotAttackableServiceException e) {
conn.sendActionFailed();
} catch (NotAttackableNPCServiceException e) {
conn.sendActionFailed();
}
}
}

View File

@@ -1,105 +0,0 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.client;
import org.jboss.netty.buffer.ChannelBuffer;
import com.google.inject.Inject;
import com.l2jserver.game.net.packet.server.SM_ACTION_FAILED;
import com.l2jserver.service.game.chat.CannotChatToSelfChatServiceException;
import com.l2jserver.service.game.chat.ChatBanActiveChatServiceException;
import com.l2jserver.service.game.chat.ChatMessageType;
import com.l2jserver.service.game.chat.ChatService;
import com.l2jserver.service.game.chat.ChatTargetOfflineServiceException;
import com.l2jserver.service.game.chat.TargetNotFoundChatServiceException;
import com.l2jserver.service.network.model.Lineage2Client;
import com.l2jserver.service.network.model.SystemMessage;
import com.l2jserver.service.network.model.packet.AbstractClientPacket;
import com.l2jserver.util.BufferUtils;
/**
* Completes the creation of an character. Creates the object, inserts into the
* database and notifies the client about the status of the operation.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class CM_CHAR_CHAT extends AbstractClientPacket {
/**
* The packet OPCODE
*/
public static final int OPCODE = 0x49;
// services and daos
/**
* The {@link ChatService} implementation
*/
private final ChatService chatService;
/**
* The message
*/
private String message;
/**
* The message destination
*/
private ChatMessageType destination;
/**
* The message target
*/
private String target;
/**
* @param chatService
* the chat service
*/
@Inject
public CM_CHAR_CHAT(ChatService chatService) {
this.chatService = chatService;
}
@Override
public void read(Lineage2Client conn, ChannelBuffer buffer) {
this.message = BufferUtils.readString(buffer);
this.destination = ChatMessageType.fromID(buffer.readInt());
if (this.destination == ChatMessageType.TELL) { // private
// message
this.target = BufferUtils.readString(buffer);
}
}
@Override
public void process(final Lineage2Client conn) {
if (message.length() == 0 || destination == null) {
conn.write(SM_ACTION_FAILED.SHARED_INSTANCE);
conn.close();
}
try {
chatService.send(conn.getCharacterID(), destination, message,
target);
} catch (TargetNotFoundChatServiceException e) {
conn.sendSystemMessage(SystemMessage.TARGET_CANT_FOUND);
} catch (CannotChatToSelfChatServiceException e) {
conn.sendSystemMessage(SystemMessage.CANNOT_USE_ON_YOURSELF);
} catch (ChatBanActiveChatServiceException e) {
conn.sendSystemMessage(SystemMessage.CHATTING_IS_CURRENTLY_PROHIBITED);
} catch (ChatTargetOfflineServiceException e) {
conn.sendSystemMessage(SystemMessage.S1_IS_NOT_ONLINE, target);
}
}
}

Some files were not shown because too many files have changed in this diff Show More