diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/.gitignore b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/.gitignore new file mode 100644 index 000000000..800f7c8c7 --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/.gitignore @@ -0,0 +1,3 @@ +/services.xml +bin/ +*.class \ No newline at end of file diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/distribution/services.xml b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/distribution/services.xml new file mode 100644 index 000000000..f66f184f0 --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/distribution/services.xml @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/pom.xml b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/pom.xml new file mode 100644 index 000000000..a5bbd9bf9 --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/pom.xml @@ -0,0 +1,51 @@ + + 4.0.0 + + l2jserver2-gameserver + com.l2jserver + 0.0.2-SNAPSHOT + .. + + l2jserver2-gameserver-interlude + + + + + org.apache.maven.plugins + maven-assembly-plugin + + + src/main/assembly/distribution-mysql5-bin.xml + src/main/assembly/distribution-orientdb-bin.xml + src/main/assembly/distribution-h2-bin.xml + src/main/assembly/distribution-derby-bin.xml + src/main/assembly/distribution-src.xml + + + + + + org.apache.maven.plugins + maven-jar-plugin + + + + true + libs/ + com.l2jserver.L2JGameServerMain + + + + + + + + + + com.l2jserver + l2jserver2-gameserver-core + 0.0.2-SNAPSHOT + + + \ No newline at end of file diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/services-sample.xml b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/services-sample.xml new file mode 100644 index 000000000..80a137d21 --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/services-sample.xml @@ -0,0 +1,154 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/assembly/distribution-bin.xml b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/assembly/distribution-bin.xml new file mode 100644 index 000000000..888bd1b6f --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/assembly/distribution-bin.xml @@ -0,0 +1,42 @@ + + + + ${project.parent.basedir}/distribution + / + + + ${project.basedir}/distribution + / + + + + + ${project.build.directory}/${project.artifactId}-${project.version}.jar + / + l2jserver2.jar + 0755 + + + ${project.parent.build.directory}/${project.parent.artifactId}-${project.version}-data.zip + / + data.zip + + + + + /libs + false + false + runtime + + mysql:* + com.orientechnologies:* + com.h2database:* + org.apache.derby:* + + + + \ No newline at end of file diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/assembly/distribution-derby-bin.xml b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/assembly/distribution-derby-bin.xml new file mode 100644 index 000000000..d57404b56 --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/assembly/distribution-derby-bin.xml @@ -0,0 +1,24 @@ + + derby-bin + + zip + + true + + src/main/assembly/distribution-bin.xml + + + + /libs + false + false + runtime + + org.apache.derby:* + + + + \ No newline at end of file diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/assembly/distribution-h2-bin.xml b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/assembly/distribution-h2-bin.xml new file mode 100644 index 000000000..719b02fdd --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/assembly/distribution-h2-bin.xml @@ -0,0 +1,24 @@ + + h2-bin + + zip + + true + + src/main/assembly/distribution-bin.xml + + + + /libs + false + false + runtime + + com.h2database:* + + + + \ No newline at end of file diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/assembly/distribution-mysql5-bin.xml b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/assembly/distribution-mysql5-bin.xml new file mode 100644 index 000000000..bf04f832a --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/assembly/distribution-mysql5-bin.xml @@ -0,0 +1,24 @@ + + mysql5-bin + + zip + + true + + src/main/assembly/distribution-bin.xml + + + + /libs + false + false + runtime + + mysql:* + + + + \ No newline at end of file diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/assembly/distribution-orientdb-bin.xml b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/assembly/distribution-orientdb-bin.xml new file mode 100644 index 000000000..fa3555f53 --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/assembly/distribution-orientdb-bin.xml @@ -0,0 +1,24 @@ + + orientdb-bin + + zip + + true + + src/main/assembly/distribution-bin.xml + + + + /libs + false + false + runtime + + com.orientechnologies:* + + + + \ No newline at end of file diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/assembly/distribution-src.xml b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/assembly/distribution-src.xml new file mode 100644 index 000000000..bc651aa46 --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/assembly/distribution-src.xml @@ -0,0 +1,32 @@ + + src + + zip + + + + + ${project.basedir} + / + + data/** + src/** + + + + ${project.basedir}/dist + / + + + + + /libs + true + false + runtime + + + \ No newline at end of file diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/InterludeLineage2Client.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/InterludeLineage2Client.java new file mode 100644 index 000000000..3746036a8 --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/InterludeLineage2Client.java @@ -0,0 +1,419 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +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). + *

+ * This class also provides handy methods for {@link #write(ServerPacket) + * writing} packets. + * + * @author Rogiel + */ +public class InterludeLineage2Client 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 InterludeLineage2Client(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. + *

+ * 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 + *

+ * 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 + *

+ * Please note that this method will not 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. + *

+ * This is an convenience method for

+ * conn.write(ActionFailedPacket.SHARED_INSTANCE);
+ * + * @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. + *

+ * This is an convenience method for

+ * conn.write(new SM_HTML(null, template));
+ * + * @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. + *

+ * This is an convenience method for

+ * conn.write(new SM_COMMUNITY_HTML(template));
+ * + * @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 items 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 items 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 items 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 + + "]"; + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/Lineage2PipelineFactory.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/Lineage2PipelineFactory.java new file mode 100644 index 000000000..1b316cc2a --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/Lineage2PipelineFactory.java @@ -0,0 +1,101 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net; + +import static org.jboss.netty.channel.Channels.pipeline; + +import org.jboss.netty.channel.ChannelPipeline; +import org.jboss.netty.channel.ChannelPipelineFactory; +import org.jboss.netty.handler.logging.LoggingHandler; +import org.jboss.netty.logging.InternalLogLevel; + +import com.google.inject.Guice; +import com.google.inject.Inject; +import com.google.inject.Injector; +import com.l2jserver.game.net.codec.Lineage2Decrypter; +import com.l2jserver.game.net.codec.Lineage2Encrypter; +import com.l2jserver.game.net.codec.Lineage2FrameDecoder; +import com.l2jserver.game.net.codec.Lineage2FrameEncoder; +import com.l2jserver.game.net.codec.Lineage2PacketReader; +import com.l2jserver.game.net.codec.Lineage2PacketWriter; +import com.l2jserver.game.net.handler.Lineage2PacketHandler; +import com.l2jserver.game.net.handler.Lineage2TimeoutHandler; +import com.l2jserver.service.network.NettyNetworkService; +import com.l2jserver.service.network.NetworkService; + +/** + * This class creates a new instance of {@link ChannelPipeline} and attaches all + * handlers and codecs. + * + * @author Rogiel + */ +public class Lineage2PipelineFactory implements ChannelPipelineFactory { + /** + * The Google Guice {@link Injector}. + */ + private final Injector injector; + /** + * The {@link NettyNetworkService} + */ + private final NettyNetworkService nettyNetworkService; + + /** + * Creates a new instance of this pipeline + * + * @param injector + * the {@link Guice} {@link Injector} + * @param networkService + * the network service + */ + @Inject + public Lineage2PipelineFactory(Injector injector, + NetworkService networkService) { + this.injector = injector; + this.nettyNetworkService = (NettyNetworkService) networkService; + } + + @Override + public ChannelPipeline getPipeline() throws Exception { + final ChannelPipeline pipeline = pipeline(); + + // pipeline.addLast("timeout.tiner", new IdleStateHandler( + // new HashedWheelTimer(), 30, 30, 0)); + + pipeline.addLast("frame.encoder", new Lineage2FrameEncoder()); + pipeline.addLast("frame.decoder", new Lineage2FrameDecoder()); + + pipeline.addLast(Lineage2Encrypter.HANDLER_NAME, + new Lineage2Encrypter()); + pipeline.addLast(Lineage2Decrypter.HANDLER_NAME, + new Lineage2Decrypter()); + + pipeline.addLast(Lineage2PacketWriter.HANDLER_NAME, + new Lineage2PacketWriter()); + pipeline.addLast(Lineage2PacketReader.HANDLER_NAME, + new Lineage2PacketReader(injector)); + + pipeline.addLast("logger", new LoggingHandler(InternalLogLevel.DEBUG, + true)); + + final Lineage2TimeoutHandler timeoutHandler = new Lineage2TimeoutHandler(); + pipeline.addLast("packet.handler", new Lineage2PacketHandler( + nettyNetworkService, timeoutHandler)); + // pipeline.addLast("timeout.handler", timeoutHandler); + + return pipeline; + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/codec/Lineage2Decrypter.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/codec/Lineage2Decrypter.java new file mode 100644 index 000000000..58df7d888 --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/codec/Lineage2Decrypter.java @@ -0,0 +1,109 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.codec; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.ChannelHandlerContext; +import org.jboss.netty.handler.codec.oneone.OneToOneDecoder; + +import com.l2jserver.service.network.model.Lineage2CryptographyKey; + +/** + * Decrypts encrypted Lineage II packets + * + * @author Rogiel + */ +public class Lineage2Decrypter extends OneToOneDecoder { + /** + * The handler name + */ + public static final String HANDLER_NAME = "crypto.decoder"; + + /** + * Enabled state + */ + private boolean enabled = false; + /** + * Crypto key + */ + private Lineage2CryptographyKey key; + + @Override + protected Object decode(ChannelHandlerContext ctx, Channel channel, + Object msg) throws Exception { + if (!(msg instanceof ChannelBuffer)) + return msg; + if (!enabled) + return msg; + final ChannelBuffer buffer = (ChannelBuffer) msg; + + final int offset = buffer.readerIndex(); + final int size = buffer.readableBytes(); + int temp = 0; + synchronized (key) { + for (int i = 0; i < size; i++) { + int temp2 = buffer.getByte(offset + i) & 0xFF; + buffer.setByte(offset + i, (temp2 ^ key.get(i) ^ temp)); + temp = temp2; + } + key.update(size); + } + + return buffer; + } + + /** + * Creates a random key and enables descrypting + * + * @param key + * the key + */ + public void enable(Lineage2CryptographyKey key) { + this.setKey(key); + this.setEnabled(true); + } + + /** + * Set this decrypter key. The key can only be set once. + * + * @param key + * the key + */ + public void setKey(Lineage2CryptographyKey key) { + if (this.key != null) + throw new IllegalStateException("Key is already set"); + this.key = key; + } + + /** + * @return true if decrypter is enabled + */ + public boolean isEnabled() { + return enabled; + } + + /** + * Sets the state of this decrypter + * + * @param enabled + * the new state + */ + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/codec/Lineage2Encrypter.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/codec/Lineage2Encrypter.java new file mode 100644 index 000000000..39786496e --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/codec/Lineage2Encrypter.java @@ -0,0 +1,109 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.codec; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.ChannelHandlerContext; +import org.jboss.netty.handler.codec.oneone.OneToOneEncoder; + +import com.l2jserver.service.network.model.Lineage2CryptographyKey; + +/** + * Encrypts Lineage II packets + * + * @author Rogiel + */ +public class Lineage2Encrypter extends OneToOneEncoder { + /** + * The handler name + */ + public static final String HANDLER_NAME = "crypto.encoder"; + + /** + * Enabled state + */ + private boolean enabled = false; + /** + * Crypto key + */ + private Lineage2CryptographyKey key; + + @Override + protected Object encode(ChannelHandlerContext ctx, Channel channel, + Object msg) throws Exception { + if (!(msg instanceof ChannelBuffer)) + return msg; + if (!enabled) + return msg; + final ChannelBuffer buffer = (ChannelBuffer) msg; + + final int offset = buffer.readerIndex() + 2; // skip header + final int size = buffer.readableBytes() - 2; + int temp = 0, temp2 = 0; + synchronized (key) { + for (int i = 0; i < size; i++) { + temp2 = buffer.getByte(offset + i) & 0xFF; + temp = temp2 ^ key.get(i) ^ temp; + buffer.setByte(offset + i, (byte) temp); + } + key.update(size); + } + + return msg; + } + + /** + * Enables this encrypter with the given key + * + * @param key + * the key + */ + public void enable(Lineage2CryptographyKey key) { + this.setKey(key); + this.setEnabled(true); + } + + /** + * Set this decrypter key. The key can only be set once. + * + * @param key + * the key + */ + public void setKey(Lineage2CryptographyKey key) { + if (this.key != null) + throw new IllegalStateException("Key is already set"); + this.key = key; + } + + /** + * @return true if this encrypter is enabled + */ + public boolean isEnabled() { + return enabled; + } + + /** + * Sets the state of this encrypter + * + * @param enabled + * the new state + */ + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/codec/Lineage2FrameDecoder.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/codec/Lineage2FrameDecoder.java new file mode 100644 index 000000000..18806405b --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/codec/Lineage2FrameDecoder.java @@ -0,0 +1,61 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.codec; + +import java.nio.ByteOrder; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.buffer.ChannelBuffers; +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.ChannelHandlerContext; +import org.jboss.netty.handler.codec.frame.FrameDecoder; + +/** + * This decoder parses Lineage II frames. Each frame is has a header of 2 bytes + * unsigned short. + * + * @author Rogiel + */ +public class Lineage2FrameDecoder extends FrameDecoder { + /** + * The message header size (in bytes) + */ + private static final int HEADER_SIZE = 2; + + @Override + protected Object decode(ChannelHandlerContext ctx, Channel channel, + ChannelBuffer oldBuffer) throws Exception { + if (oldBuffer.readableBytes() < 2) + return null; + ChannelBuffer buffer = ChannelBuffers.wrappedBuffer(oldBuffer + .toByteBuffer().order(ByteOrder.LITTLE_ENDIAN)); + + buffer.markReaderIndex(); + final int pending = buffer.readUnsignedShort() - HEADER_SIZE; + if (pending == 0) + return null; + if (buffer.readableBytes() < pending) { + buffer.resetReaderIndex(); + return null; + } + + final ChannelBuffer b = buffer.copy(buffer.readerIndex(), pending); + oldBuffer.skipBytes(pending + HEADER_SIZE); + return ChannelBuffers.wrappedBuffer(b.toByteBuffer().order( + ByteOrder.LITTLE_ENDIAN)); + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/codec/Lineage2FrameEncoder.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/codec/Lineage2FrameEncoder.java new file mode 100644 index 000000000..e9beadb05 --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/codec/Lineage2FrameEncoder.java @@ -0,0 +1,41 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.codec; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.ChannelHandlerContext; +import org.jboss.netty.handler.codec.oneone.OneToOneEncoder; + +/** + * This encoder creates Lineage II frames. Each frame is has a header of 2 bytes + * unsigned short. + * + * @author Rogiel + */ +public class Lineage2FrameEncoder extends OneToOneEncoder { + @Override + protected Object encode(ChannelHandlerContext ctx, Channel channel, + Object msg) throws Exception { + if (!(msg instanceof ChannelBuffer)) + return msg; + final ChannelBuffer buffer = (ChannelBuffer) msg; + buffer.setShort(0, buffer.readableBytes()); + + return buffer; + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/codec/Lineage2PacketReader.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/codec/Lineage2PacketReader.java new file mode 100644 index 000000000..c4ffbf21a --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/codec/Lineage2PacketReader.java @@ -0,0 +1,226 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.codec; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.ChannelHandlerContext; +import org.jboss.netty.handler.codec.oneone.OneToOneDecoder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.inject.Inject; +import com.google.inject.Injector; +import com.l2jserver.game.net.packet.client.CM_ACTION_USE; +import com.l2jserver.game.net.packet.client.CM_ADMIN_COMMAND; +import com.l2jserver.game.net.packet.client.CM_AUTH_LOGIN; +import com.l2jserver.game.net.packet.client.CM_BYPASS; +import com.l2jserver.game.net.packet.client.CM_CHAR_ACTION; +import com.l2jserver.game.net.packet.client.CM_CHAR_APPEARING; +import com.l2jserver.game.net.packet.client.CM_CHAR_ATTACK; +import com.l2jserver.game.net.packet.client.CM_CHAR_CHAT; +import com.l2jserver.game.net.packet.client.CM_CHAR_CREATE; +import com.l2jserver.game.net.packet.client.CM_CHAR_MOVE; +import com.l2jserver.game.net.packet.client.CM_CHAR_OPEN_MAP; +import com.l2jserver.game.net.packet.client.CM_CHAR_POSITION; +import com.l2jserver.game.net.packet.client.CM_CHAR_REQ_INVENTORY; +import com.l2jserver.game.net.packet.client.CM_CHAR_SELECT; +import com.l2jserver.game.net.packet.client.CM_CHAR_SHORTCUT_CREATE; +import com.l2jserver.game.net.packet.client.CM_CHAR_SHORTCUT_REMOVE; +import com.l2jserver.game.net.packet.client.CM_CHAR_TARGET_UNSELECT; +import com.l2jserver.game.net.packet.client.CM_ENTER_WORLD; +import com.l2jserver.game.net.packet.client.CM_EXT_REQ_ALL_FORTRESS_INFO; +import com.l2jserver.game.net.packet.client.CM_EXT_REQ_KEY_MAPPING; +import com.l2jserver.game.net.packet.client.CM_EXT_REQ_MANOR_LIST; +import com.l2jserver.game.net.packet.client.CM_GG_KEY; +import com.l2jserver.game.net.packet.client.CM_GOTO_LOBBY; +import com.l2jserver.game.net.packet.client.CM_ITEM_DESTROY; +import com.l2jserver.game.net.packet.client.CM_ITEM_DROP; +import com.l2jserver.game.net.packet.client.CM_LOGOUT; +import com.l2jserver.game.net.packet.client.CM_PROTOCOL_VERSION; +import com.l2jserver.game.net.packet.client.CM_REQUEST_CHAR_TEMPLATE; +import com.l2jserver.game.net.packet.client.CM_RESTART; +import com.l2jserver.service.network.model.Lineage2Client; +import com.l2jserver.service.network.model.packet.ClientPacket; + +/** + * This decoder reads an frame and decodes the packet in it. Each packet has an + * fixed single opcode byte. Once the packet has been identified, reading is + * done by the {@link ClientPacket} class. + *

+ * Note that some packets have an additional opcode. This class also handle + * those cases. + * + * @author Rogiel + */ +public class Lineage2PacketReader extends OneToOneDecoder { + /** + * The handler name + */ + public static final String HANDLER_NAME = "packet.reader"; + + /** + * The Google Guice {@link Injector} + */ + private final Injector injector; + /** + * The logger + */ + private final Logger logger = LoggerFactory + .getLogger(Lineage2PacketReader.class); + + /** + * The active Lineage 2 connection + */ + private Lineage2Client connection; + + /** + * Creates a new instance + * + * @param injector + * the injector + */ + @Inject + public Lineage2PacketReader(Injector injector) { + this.injector = injector; + } + + @Override + protected Object decode(ChannelHandlerContext ctx, Channel channel, + Object msg) throws Exception { + if (!(msg instanceof ChannelBuffer)) + return msg; + final ChannelBuffer buffer = (ChannelBuffer) msg; + final ClientPacket packet = createPacket(getPacketClass(buffer)); + if (packet == null) + return null; + packet.read(connection, buffer); + return packet; + } + + /** + * Crates a new instance of the packet type + * + * @param type + * the packet type + * @return the created packet + */ + private ClientPacket createPacket(Class type) { + if (type == null) + return null; + return injector.getInstance(type); + } + + /** + * Discovers the packet type + * + * @param buffer + * the buffer + * @return the packet class + */ + private Class getPacketClass(ChannelBuffer buffer) { + final short opcode = buffer.readUnsignedByte(); + switch (opcode) { + case CM_LOGOUT.OPCODE: + return CM_LOGOUT.class; + case CM_PROTOCOL_VERSION.OPCODE: + return CM_PROTOCOL_VERSION.class; + case CM_AUTH_LOGIN.OPCODE: + return CM_AUTH_LOGIN.class; + case CM_CHAR_CREATE.OPCODE: + return CM_CHAR_CREATE.class; + case CM_REQUEST_CHAR_TEMPLATE.OPCODE: + return CM_REQUEST_CHAR_TEMPLATE.class; + case 0xd0: // CM_REQ_************** + final int opcode2 = buffer.readUnsignedShort(); + switch (opcode2) { + case CM_GOTO_LOBBY.OPCODE2: + return CM_GOTO_LOBBY.class; + case CM_EXT_REQ_KEY_MAPPING.OPCODE2: + return CM_EXT_REQ_KEY_MAPPING.class; + case CM_EXT_REQ_MANOR_LIST.OPCODE2: + return CM_EXT_REQ_MANOR_LIST.class; + case CM_EXT_REQ_ALL_FORTRESS_INFO.OPCODE2: + return CM_EXT_REQ_ALL_FORTRESS_INFO.class; + default: + logger.warn("Unknown packet for 0xd0{}", + Integer.toHexString(opcode2)); + break; + } + break; + case CM_CHAR_SELECT.OPCODE: + return CM_CHAR_SELECT.class; + case CM_GG_KEY.OPCODE: + return CM_GG_KEY.class; + case CM_CHAR_MOVE.OPCODE: + return CM_CHAR_MOVE.class; + case CM_RESTART.OPCODE: + return CM_RESTART.class; + case CM_CHAR_CHAT.OPCODE: + return CM_CHAR_CHAT.class; + case CM_CHAR_POSITION.OPCODE: + return CM_CHAR_POSITION.class; + case CM_ENTER_WORLD.OPCODE: + return CM_ENTER_WORLD.class; + case CM_CHAR_ACTION.OPCODE: + return CM_CHAR_ACTION.class; + case CM_CHAR_REQ_INVENTORY.OPCODE: + return CM_CHAR_REQ_INVENTORY.class; + case CM_ADMIN_COMMAND.OPCODE: + return CM_ADMIN_COMMAND.class; + case CM_BYPASS.OPCODE: + return CM_BYPASS.class; + case CM_CHAR_APPEARING.OPCODE: + return CM_CHAR_APPEARING.class; + case CM_ACTION_USE.OPCODE: + return CM_ACTION_USE.class; + case CM_CHAR_OPEN_MAP.OPCODE: + return CM_CHAR_OPEN_MAP.class; + case CM_CHAR_ATTACK.OPCODE: + return CM_CHAR_ATTACK.class; + case CM_ITEM_DROP.OPCODE: + return CM_ITEM_DROP.class; + case CM_ITEM_DESTROY.OPCODE: + return CM_ITEM_DESTROY.class; + case CM_CHAR_TARGET_UNSELECT.OPCODE: + return CM_CHAR_TARGET_UNSELECT.class; + case CM_CHAR_SHORTCUT_CREATE.OPCODE: + return CM_CHAR_SHORTCUT_CREATE.class; + case CM_CHAR_SHORTCUT_REMOVE.OPCODE: + return CM_CHAR_SHORTCUT_REMOVE.class; + default: + logger.warn("Unknown packet for 0x{}", Integer.toHexString(opcode)); + break; + } + return null; + } + + /** + * @return the connection + */ + public Lineage2Client getConnection() { + return connection; + } + + /** + * @param connection + * the connection to set + */ + public void setConnection(Lineage2Client connection) { + this.connection = connection; + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/codec/Lineage2PacketWriter.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/codec/Lineage2PacketWriter.java new file mode 100644 index 000000000..12225669b --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/codec/Lineage2PacketWriter.java @@ -0,0 +1,77 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.codec; + +import java.nio.ByteOrder; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.buffer.ChannelBuffers; +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.ChannelHandlerContext; +import org.jboss.netty.handler.codec.oneone.OneToOneEncoder; + +import com.l2jserver.service.network.model.Lineage2Client; +import com.l2jserver.service.network.model.packet.ServerPacket; + +/** + * This encoder writes the frame content and encodes the packet in it. Each + * packet has an fixed single opcode byte. Once the packet opcode has been + * written, packet data is written by the {@link ServerPacket} class. + * + * @author Rogiel + */ +public class Lineage2PacketWriter extends OneToOneEncoder { + /** + * The handler name + */ + public static final String HANDLER_NAME = "packet.writer"; + + /** + * The active Lineage 2 connection + */ + private Lineage2Client connection; + + @Override + protected Object encode(ChannelHandlerContext ctx, Channel channel, + Object msg) throws Exception { + if (!(msg instanceof ServerPacket)) + return msg; + final ChannelBuffer buffer = ChannelBuffers.dynamicBuffer( + ByteOrder.LITTLE_ENDIAN, 10); + final ServerPacket packet = (ServerPacket) msg; + buffer.writeShort(0); // wrap 2 bytes for packet length + buffer.writeByte(packet.getOpcode()); // packet opcode + packet.write(connection, buffer); + + return buffer; + } + + /** + * @return the connection + */ + public Lineage2Client getConnection() { + return connection; + } + + /** + * @param connection + * the connection to set + */ + public void setConnection(Lineage2Client connection) { + this.connection = connection; + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/handler/Lineage2PacketHandler.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/handler/Lineage2PacketHandler.java new file mode 100644 index 000000000..5c9a10973 --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/handler/Lineage2PacketHandler.java @@ -0,0 +1,140 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.handler; + +import java.io.IOException; + +import org.jboss.netty.channel.ChannelException; +import org.jboss.netty.channel.ChannelHandlerContext; +import org.jboss.netty.channel.ChannelStateEvent; +import org.jboss.netty.channel.ExceptionEvent; +import org.jboss.netty.channel.MessageEvent; +import org.jboss.netty.channel.SimpleChannelHandler; + +import com.google.common.base.Throwables; +import com.l2jserver.game.net.InterludeLineage2Client; +import com.l2jserver.service.network.NettyNetworkService; +import com.l2jserver.service.network.model.Lineage2Client; +import com.l2jserver.service.network.model.packet.ClientPacket; +import com.l2jserver.util.html.markup.HtmlTemplate; +import com.l2jserver.util.html.markup.MarkupTag; + +/** + * This handler dispatches the {@link ClientPacket#process(Lineage2Client)} + * method and creates a new {@link Lineage2Client} once a new channel is open. + * + * @author Rogiel + */ +public class Lineage2PacketHandler extends SimpleChannelHandler { + /** + * The {@link NettyNetworkService} + */ + private final NettyNetworkService nettyNetworkService; + /** + * The timeout handler is responsible for disconnecting idle clients. + */ + private final Lineage2TimeoutHandler timeoutHandler; + /** + * The Lineage 2 connection + */ + private InterludeLineage2Client connection; + + /** + * Creates a new instance of the packet handler + * + * @param nettyNetworkService + * the netty network service + * @param timeoutHandler + * the timeout handler + */ + public Lineage2PacketHandler(NettyNetworkService nettyNetworkService, + Lineage2TimeoutHandler timeoutHandler) { + this.nettyNetworkService = nettyNetworkService; + this.timeoutHandler = timeoutHandler; + } + + @Override + public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e) + throws Exception { + connection = new InterludeLineage2Client(e.getChannel()); + connection.getPacketWriter().setConnection(connection); + timeoutHandler.setConnection(connection); + + nettyNetworkService.register(connection); + + super.channelOpen(ctx, e); + } + + @Override + public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) + throws Exception { + final Object msg = e.getMessage(); + if (!(msg instanceof ClientPacket)) + return; + final ClientPacket packet = (ClientPacket) msg; + packet.process(connection); + super.messageReceived(ctx, e); + } + + @Override + public void writeRequested(ChannelHandlerContext ctx, MessageEvent e) + throws Exception { + super.writeRequested(ctx, e); + } + + @Override + public void channelDisconnected(ChannelHandlerContext ctx, + ChannelStateEvent e) throws Exception { + nettyNetworkService.unregister(connection); + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent event) + throws Exception { + final Throwable e = event.getCause(); + try { + if (e instanceof ChannelException) + return; + if (e instanceof IOException) + return; + if (!connection.isConnected()) + // no point sending error messages if the client is disconnected + return; + + // TODO only send exception stack trace in development mode! + final String exception = Throwables.getStackTraceAsString(e) + .replaceAll("\n", "
").replace(" ", ""); + final HtmlTemplate template = new HtmlTemplate("Java Exception") { + @Override + public void build(MarkupTag body) { + body.text(exception); + } + }; + connection.sendHTML(template); + // order client not to wait any packet + connection.sendActionFailed(); + + final String[] lines = Throwables.getStackTraceAsString(e).split( + "\n"); + for (final String line : lines) { + connection.sendMessage(line); + } + } finally { + e.printStackTrace(); + } + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/handler/Lineage2TimeoutHandler.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/handler/Lineage2TimeoutHandler.java new file mode 100644 index 000000000..0af6f1838 --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/handler/Lineage2TimeoutHandler.java @@ -0,0 +1,58 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.handler; + +import org.jboss.netty.channel.ChannelHandlerContext; +import org.jboss.netty.handler.timeout.IdleStateAwareChannelHandler; +import org.jboss.netty.handler.timeout.IdleStateEvent; + +import com.l2jserver.service.network.model.Lineage2Client; + +/** + * @author Rogiel + * + */ +public class Lineage2TimeoutHandler extends IdleStateAwareChannelHandler { + /** + * The Lineage 2 connection + */ + private Lineage2Client connection; + + @Override + public void channelIdle(ChannelHandlerContext ctx, IdleStateEvent e) + throws Exception { + if (connection != null) { + connection.close(); + } + super.channelIdle(ctx, e); + } + + /** + * @return the connection + */ + protected Lineage2Client getConnection() { + return connection; + } + + /** + * @param connection + * the connection to set + */ + protected void setConnection(Lineage2Client connection) { + this.connection = connection; + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_ACTION_USE.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_ACTION_USE.java new file mode 100644 index 000000000..b0518fda5 --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_ACTION_USE.java @@ -0,0 +1,205 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +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 Rogiel + */ +public class CM_ACTION_USE extends AbstractClientPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0x45; + + /** + * The {@link CharacterService} + */ + private final CharacterService charService; + + /** + * The action to be performed + */ + private Action action; + + /** + * The enumeration of all possible actions + * + * @author Rogiel + */ + 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; + } + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_ADMIN_COMMAND.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_ADMIN_COMMAND.java new file mode 100644 index 000000000..eff876b2e --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_ADMIN_COMMAND.java @@ -0,0 +1,94 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.packet.client; + +import java.util.StringTokenizer; + +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.ArrayUtils; +import com.l2jserver.util.BufferUtils; + +/** + * Executes an administrator action + * + * @author Rogiel + */ +public class CM_ADMIN_COMMAND extends AbstractClientPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0x5b; + + /** + * The admin service + */ + private final AdministratorService adminService; + + /** + * The command + */ + 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 = ; + // 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(), tokenizer.nextToken(), ArrayUtils.createArgumentArray(tokenizer)); + } catch (ServiceException e) { + conn.sendMessage("Invalid administrator command or syntax"); + } finally { + conn.sendActionFailed(); + } + + // TODO implement admin commands + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_AUTH_LOGIN.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_AUTH_LOGIN.java new file mode 100644 index 000000000..3839c626d --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_AUTH_LOGIN.java @@ -0,0 +1,145 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +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 Rogiel + */ +public class CM_AUTH_LOGIN extends AbstractClientPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0x08; + + /** + * 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 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; + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_BYPASS.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_BYPASS.java new file mode 100644 index 000000000..fa03fffc5 --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_BYPASS.java @@ -0,0 +1,120 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +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.ArrayUtils; +import com.l2jserver.util.BufferUtils; + +/** + * Executes an bypass command + * + * @author Rogiel + */ +public class CM_BYPASS extends AbstractClientPacket { + /** + * The logger + */ + private final Logger log = LoggerFactory.getLogger(this.getClass()); + + /** + * The packet OPCODE + */ + public static final int OPCODE = 0x21; + + /** + * 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 id = idResolver.resolve(objectId); + if (!(id instanceof NPCID)) { + conn.sendActionFailed(); + return; + } + final NPC npc = id.getObject(); + try { + npcService.action(npc, conn.getCharacter(), + ArrayUtils.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; + } + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_CHAR_ACTION.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_CHAR_ACTION.java new file mode 100644 index 000000000..d9a19108e --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_CHAR_ACTION.java @@ -0,0 +1,142 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +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 Rogiel + */ +public class CM_CHAR_ACTION extends AbstractClientPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0x4; + + /** + * 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; + } + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_CHAR_APPEARING.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_CHAR_APPEARING.java new file mode 100644 index 000000000..311470d39 --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_CHAR_APPEARING.java @@ -0,0 +1,65 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +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 Rogiel + */ +public class CM_CHAR_APPEARING extends AbstractClientPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0x30; + + /** + * 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(); + } + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_CHAR_ATTACK.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_CHAR_ATTACK.java new file mode 100644 index 000000000..48f2bc2e3 --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_CHAR_ATTACK.java @@ -0,0 +1,166 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +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 Rogiel + */ +public class CM_CHAR_ATTACK extends AbstractClientPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0x0A; + + /** + * 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 Rogiel + */ + 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 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(); + } + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_CHAR_CHAT.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_CHAR_CHAT.java new file mode 100644 index 000000000..a97291b86 --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_CHAR_CHAT.java @@ -0,0 +1,105 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +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 Rogiel + */ +public class CM_CHAR_CHAT extends AbstractClientPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0x38; + + // 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); + } + + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_CHAR_CREATE.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_CHAR_CREATE.java new file mode 100644 index 000000000..ded6988e0 --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_CHAR_CREATE.java @@ -0,0 +1,190 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.packet.client; + +import static com.l2jserver.game.net.packet.server.SM_CHAR_CREATE_FAIL.Reason.REASON_16_ENG_CHARS; +import static com.l2jserver.game.net.packet.server.SM_CHAR_CREATE_FAIL.Reason.REASON_CHOOSE_ANOTHER_SVR; +import static com.l2jserver.game.net.packet.server.SM_CHAR_CREATE_FAIL.Reason.REASON_CREATION_FAILED; +import static com.l2jserver.game.net.packet.server.SM_CHAR_CREATE_FAIL.Reason.REASON_NAME_ALREADY_EXISTS; +import static com.l2jserver.game.net.packet.server.SM_CHAR_CREATE_FAIL.Reason.REASON_TOO_MANY_CHARACTERS; + +import org.jboss.netty.buffer.ChannelBuffer; + +import com.google.inject.Inject; +import com.l2jserver.game.net.packet.server.SM_CHAR_CREATE_OK; +import com.l2jserver.model.template.actor.ActorSex; +import com.l2jserver.model.template.character.CharacterClass; +import com.l2jserver.model.template.character.CharacterRace; +import com.l2jserver.model.world.L2Character; +import com.l2jserver.model.world.character.CharacterAppearance.CharacterFace; +import com.l2jserver.model.world.character.CharacterAppearance.CharacterHairColor; +import com.l2jserver.model.world.character.CharacterAppearance.CharacterHairStyle; +import com.l2jserver.service.game.character.CharacteCreationNotAllowedException; +import com.l2jserver.service.game.character.CharacterInvalidAppearanceException; +import com.l2jserver.service.game.character.CharacterInvalidNameException; +import com.l2jserver.service.game.character.CharacterInvalidRaceException; +import com.l2jserver.service.game.character.CharacterInvalidSexException; +import com.l2jserver.service.game.character.CharacterNameAlreadyExistsException; +import com.l2jserver.service.game.character.CharacterService; +import com.l2jserver.service.game.character.TooManyCharactersException; +import com.l2jserver.service.network.model.Lineage2Client; +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 Rogiel + */ +public class CM_CHAR_CREATE extends AbstractClientPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0x0b; + + // services and daos + /** + * The {@link CharacterService} implementation + */ + private final CharacterService characterService; + + // packet + /** + * The name of the new character + */ + private String name; + /** + * The race of the new character. Note that this is ignored and the template + * value is used. + */ + @SuppressWarnings("unused") + private CharacterRace race; + /** + * The sex of the new character. Note that this is ignored and the template + * value is used. + */ + private ActorSex sex; + /** + * The class of the new character + */ + private CharacterClass characterClass; + + /** + * The new character intelligence. Note that this is ignored and the + * template value is used. + */ + @SuppressWarnings("unused") + private int intelligence; + /** + * The new character intelligence. Note that this is ignored and the + * template value is used. + */ + @SuppressWarnings("unused") + private int strength; + /** + * The new character strength. Note that this is ignored and the template + * value is used. + */ + @SuppressWarnings("unused") + private int concentration; + /** + * The new character concentration. Note that this is ignored and the + * template value is used. + */ + @SuppressWarnings("unused") + private int mentality; + /** + * The new character mentality. Note that this is ignored and the template + * value is used. + */ + @SuppressWarnings("unused") + private int dexterity; + /** + * The new character dexterity. Note that this is ignored and the template + * value is used. + */ + @SuppressWarnings("unused") + private int witness; + + /** + * The new character hair style + */ + private CharacterHairStyle hairStyle; + /** + * The new character hair color + */ + private CharacterHairColor hairColor; + /** + * The new character face + */ + private CharacterFace face; + + /** + * @param characterService + * the character service + */ + @Inject + public CM_CHAR_CREATE(CharacterService characterService) { + this.characterService = characterService; + } + + @Override + public void read(Lineage2Client conn, ChannelBuffer buffer) { + name = BufferUtils.readString(buffer); + race = CharacterRace.fromOption(buffer.readInt()); + sex = ActorSex.fromOption(buffer.readInt()); + characterClass = CharacterClass.fromID(buffer.readInt()); + + intelligence = buffer.readInt(); + strength = buffer.readInt(); + concentration = buffer.readInt(); + mentality = buffer.readInt(); + dexterity = buffer.readInt(); + witness = buffer.readInt(); + + hairStyle = CharacterHairStyle.fromOption(buffer.readInt()); + hairColor = CharacterHairColor.fromOption(buffer.readInt()); + face = CharacterFace.fromOption(buffer.readInt()); + } + + @Override + public void process(final Lineage2Client conn) { + try { + final L2Character character = characterService.create(name, conn + .getSession().getAccountID(), sex, characterClass, + hairStyle, hairColor, face); + + if (character != null) + conn.write(SM_CHAR_CREATE_OK.INSTANCE); + else + conn.write(REASON_CREATION_FAILED.newInstance()); + } catch (CharacterInvalidNameException e) { + conn.write(REASON_16_ENG_CHARS.newInstance()); + } catch (CharacterInvalidAppearanceException e) { + conn.write(REASON_CREATION_FAILED.newInstance()); + } catch (CharacterNameAlreadyExistsException e) { + conn.write(REASON_NAME_ALREADY_EXISTS.newInstance()); + } catch (CharacteCreationNotAllowedException e) { + conn.write(REASON_CREATION_FAILED.newInstance()); + } catch (CharacterInvalidRaceException | CharacterInvalidSexException e) { + conn.write(REASON_CHOOSE_ANOTHER_SVR.newInstance()); + } catch (TooManyCharactersException e) { + conn.write(REASON_TOO_MANY_CHARACTERS.newInstance()); + } + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_CHAR_MOVE.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_CHAR_MOVE.java new file mode 100644 index 000000000..4b9de163f --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_CHAR_MOVE.java @@ -0,0 +1,150 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +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_CHAR_STOP; +import com.l2jserver.model.world.L2Character; +import com.l2jserver.service.game.character.CharacterService; +import com.l2jserver.service.network.model.Lineage2Client; +import com.l2jserver.service.network.model.packet.AbstractClientPacket; +import com.l2jserver.util.geometry.Coordinate; + +/** + * This packet notifies the server which character the player has chosen to use. + * + * @author Rogiel + */ +public class CM_CHAR_MOVE 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; + + // packet + /** + * The movement target + */ + private Coordinate target; + /** + * The movement origin + */ + private Coordinate origin; + /** + * The movement type + */ + @SuppressWarnings("unused") + private MovementType type; + + /** + * Defines the movement action type + * + * @author Rogiel + */ + public enum MovementType { + /** + * The move action was issued by the mouse + */ + MOUSE(0x01), + /** + * The move action was issued by the keyboard + */ + KEYBOARD(0x00); + + /** + * The type id + */ + public final int id; + + /** + * @param id + * the type id + */ + MovementType(int id) { + this.id = id; + } + + /** + * @param id + * the type id + * @return the {@link MovementType} represented by id + */ + public static MovementType fromID(int id) { + for (final MovementType type : values()) { + if (type.id == id) + return type; + } + return null; + } + } + + /** + * @param charService + * the character service + */ + @Inject + public CM_CHAR_MOVE(CharacterService charService) { + this.charService = charService; + } + + @Override + public void read(Lineage2Client conn, ChannelBuffer buffer) { + this.target = Coordinate.fromXYZ(buffer.readInt(), buffer.readInt(), + buffer.readInt()); + this.origin = Coordinate.fromXYZ(buffer.readInt(), buffer.readInt(), + buffer.readInt()); + // seems that L2Walker does not send this + if (buffer.readableBytes() >= 4) { + // 0 keyboard, 1 mouse + this.type = MovementType.fromID(buffer.readInt()); + } + } + + @Override + public void process(final Lineage2Client conn) { + if (target.equals(origin)) { + log.debug("Target is same as origin. Stopping character."); + conn.write(new SM_CHAR_STOP(conn.getCharacter())); + return; + } + if (target.getDistance(origin) >= 98010000) { + log.warn( + "Character {} is trying to move a really big distance: {}", + conn.getCharacter(), target.getDistance(origin)); + // TODO send action failed message! + return; + } + final L2Character character = conn.getCharacter(); + log.debug("Character {} is moving from {} to {}", new Object[] { + character, origin, target }); + charService.move(character, target); + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_CHAR_OPEN_MAP.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_CHAR_OPEN_MAP.java new file mode 100644 index 000000000..7b2fa22b6 --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_CHAR_OPEN_MAP.java @@ -0,0 +1,44 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.packet.client; + +import org.jboss.netty.buffer.ChannelBuffer; + +import com.l2jserver.game.net.packet.server.SM_CHAR_OPEN_MAP; +import com.l2jserver.service.network.model.Lineage2Client; +import com.l2jserver.service.network.model.packet.AbstractClientPacket; + +/** + * Executes an bypass command + * + * @author Rogiel + */ +public class CM_CHAR_OPEN_MAP extends AbstractClientPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0xcd; + + @Override + public void read(Lineage2Client conn, ChannelBuffer buffer) { + } + + @Override + public void process(final Lineage2Client conn) { + conn.write(new SM_CHAR_OPEN_MAP(1665)); + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_CHAR_POSITION.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_CHAR_POSITION.java new file mode 100644 index 000000000..ec48cb90a --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_CHAR_POSITION.java @@ -0,0 +1,74 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.packet.client; + +import org.jboss.netty.buffer.ChannelBuffer; + +import com.google.inject.Inject; +import com.l2jserver.service.game.character.CharacterService; +import com.l2jserver.service.network.model.Lineage2Client; +import com.l2jserver.service.network.model.packet.AbstractClientPacket; +import com.l2jserver.util.geometry.Point3D; + +/** + * This packet validates the character position. + * + * + * @author Rogiel + */ +public class CM_CHAR_POSITION extends AbstractClientPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0x48; + + /** + * The {@link CharacterService} + */ + private final CharacterService charService; + + /** + * The current position point + */ + private Point3D point; + /** + * Extra data -> vehicle id + */ + @SuppressWarnings("unused") + private int extra; // vehicle id + + /** + * @param charService + * the character service + */ + @Inject + public CM_CHAR_POSITION(CharacterService charService) { + this.charService = charService; + } + + @Override + public void read(Lineage2Client conn, ChannelBuffer buffer) { + point = Point3D.fromXYZA(buffer.readInt(), buffer.readInt(), + buffer.readInt(), buffer.readInt()); + extra = buffer.readInt(); + } + + @Override + public void process(final Lineage2Client conn) { + charService.receivedValidation(conn.getCharacter(), point); + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_CHAR_REQ_INVENTORY.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_CHAR_REQ_INVENTORY.java new file mode 100644 index 000000000..2803da095 --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_CHAR_REQ_INVENTORY.java @@ -0,0 +1,46 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.packet.client; + +import org.jboss.netty.buffer.ChannelBuffer; + +import com.l2jserver.game.net.packet.server.SM_CHAR_INVENTORY; +import com.l2jserver.model.world.L2Character; +import com.l2jserver.service.network.model.Lineage2Client; +import com.l2jserver.service.network.model.packet.AbstractClientPacket; + +/** + * Requests character inventory items from server. + * + * @author Rogiel + */ +public class CM_CHAR_REQ_INVENTORY extends AbstractClientPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0x1b; + + @Override + public void read(Lineage2Client conn, ChannelBuffer buffer) { + } + + @Override + public void process(final Lineage2Client conn) { + final L2Character character = conn.getCharacter(); + conn.write(new SM_CHAR_INVENTORY(character.getInventory())); + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_CHAR_SELECT.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_CHAR_SELECT.java new file mode 100644 index 000000000..f1e666ab7 --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_CHAR_SELECT.java @@ -0,0 +1,77 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +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_SELECTED; +import com.l2jserver.model.dao.CharacterDAO; +import com.l2jserver.model.world.L2Character; +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 Rogiel + */ +public class CM_CHAR_SELECT extends AbstractClientPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0x0d; + + /** + * The {@link CharacterDAO} implementation + */ + private final CharacterDAO characterDao; + + // packet + /** + * The character slot + */ + private int slot; + + /** + * @param characterDao + * the character dao + */ + @Inject + public CM_CHAR_SELECT(CharacterDAO characterDao) { + this.characterDao = characterDao; + } + + @Override + public void read(Lineage2Client conn, ChannelBuffer buffer) { + slot = buffer.readInt(); + } + + @Override + public void process(final Lineage2Client conn) { + final List chars = characterDao.selectByAccount(conn + .getSession().getAccountID()); + + // FIXME better handling! this will throw an exception sooner or later + final L2Character character = chars.get(slot); + conn.setCharacterID(character.getID()); + + conn.write(new SM_CHAR_SELECTED(chars.get(slot))); + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_CHAR_SHORTCUT_CREATE.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_CHAR_SHORTCUT_CREATE.java new file mode 100644 index 000000000..483aa86ef --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_CHAR_SHORTCUT_CREATE.java @@ -0,0 +1,125 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.packet.client; + +import org.jboss.netty.buffer.ChannelBuffer; + +import com.google.inject.Inject; +import com.l2jserver.model.game.CharacterShortcut.ShortcutActorType; +import com.l2jserver.model.game.CharacterShortcut.ShortcutType; +import com.l2jserver.model.id.object.ItemID; +import com.l2jserver.model.id.object.provider.ItemIDProvider; +import com.l2jserver.model.world.Item; +import com.l2jserver.model.world.L2Character; +import com.l2jserver.service.game.character.ShortcutService; +import com.l2jserver.service.game.character.ShortcutSlotNotFreeServiceException; +import com.l2jserver.service.network.model.Lineage2Client; +import com.l2jserver.service.network.model.packet.AbstractClientPacket; + +/** + * Sent when client adds a shortcut to shortcut bar. + * + * @author Rogiel + */ +public class CM_CHAR_SHORTCUT_CREATE extends AbstractClientPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0x33; + + /** + * The {@link ShortcutService} + */ + private final ShortcutService shortcutService; + /** + * The {@link ItemID} provider + */ + private final ItemIDProvider itemIdProvider; + + /** + * The shortcut type + */ + private ShortcutType type; + /** + * The shortcut object ID (depends on type) + */ + private int objectId; + /** + * The slot + */ + private int slot; + /** + * The page + */ + private int page; + /** + * The skill level + */ + @SuppressWarnings("unused") + private int level; + /** + * Whether the shortcut is an for an character(1) or a pet(2) + */ + @SuppressWarnings("unused") + private ShortcutActorType actorType; + + /** + * @param shortcutService + * the shortcut service + * @param itemIdProvider + * the item id provider + */ + @Inject + private CM_CHAR_SHORTCUT_CREATE(ShortcutService shortcutService, + ItemIDProvider itemIdProvider) { + this.shortcutService = shortcutService; + this.itemIdProvider = itemIdProvider; + } + + @Override + public void read(Lineage2Client conn, ChannelBuffer buffer) { + type = ShortcutType.fromID(buffer.readInt()); + int slot = buffer.readInt(); + objectId = buffer.readInt(); + level = buffer.readInt(); +// actorType = ShortcutActorType.fromID(buffer.readInt()); FIXME interlude needs this? + + this.slot = slot % 12; + this.page = slot / 12; + } + + @Override + public void process(final Lineage2Client conn) { + final L2Character character = conn.getCharacter(); + try { + switch (type) { + case ITEM: + final ItemID itemID = itemIdProvider.resolveID(objectId); + final Item item = itemID.getObject(); + if (item == null) { + conn.sendActionFailed(); + return; + } + shortcutService.create(character, item, page, slot); + break; + } + //TODO action, macro, recipe + } catch (ShortcutSlotNotFreeServiceException e) { + conn.sendActionFailed(); + } + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_CHAR_SHORTCUT_REMOVE.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_CHAR_SHORTCUT_REMOVE.java new file mode 100644 index 000000000..9baa9d514 --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_CHAR_SHORTCUT_REMOVE.java @@ -0,0 +1,77 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.packet.client; + +import org.jboss.netty.buffer.ChannelBuffer; + +import com.google.inject.Inject; +import com.l2jserver.service.game.character.ShortcutService; +import com.l2jserver.service.game.character.ShortcutSlotEmptyServiceException; +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 Rogiel + */ +public class CM_CHAR_SHORTCUT_REMOVE extends AbstractClientPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0x35; + + /** + * The {@link ShortcutService} + */ + private final ShortcutService shortcutService; + + /** + * The slot + */ + private int slot; + /** + * The page + */ + private int page; + + /** + * @param shortcutService + * the shortcut service + */ + @Inject + private CM_CHAR_SHORTCUT_REMOVE(ShortcutService shortcutService) { + this.shortcutService = shortcutService; + } + + @Override + public void read(Lineage2Client conn, ChannelBuffer buffer) { + int slot = buffer.readInt(); + this.slot = slot % 12; + this.page = slot / 12; + } + + @Override + public void process(final Lineage2Client conn) { + try { + shortcutService.remove(conn.getCharacter(), page, slot); + } catch (ShortcutSlotEmptyServiceException e) { + conn.sendActionFailed(); + } + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_CHAR_TARGET_UNSELECT.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_CHAR_TARGET_UNSELECT.java new file mode 100644 index 000000000..9b21d4082 --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_CHAR_TARGET_UNSELECT.java @@ -0,0 +1,72 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.packet.client; + +import org.jboss.netty.buffer.ChannelBuffer; + +import com.google.inject.Inject; +import com.l2jserver.service.game.character.CannotSetTargetServiceException; +import com.l2jserver.service.game.character.CharacterService; +import com.l2jserver.service.network.model.Lineage2Client; +import com.l2jserver.service.network.model.SystemMessage; +import com.l2jserver.service.network.model.packet.AbstractClientPacket; + +/** + * This packet cancels the target selection + * + * @author Rogiel + */ +public class CM_CHAR_TARGET_UNSELECT extends AbstractClientPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0x37; + + /** + * The {@link CharacterService} + */ + private final CharacterService charService; + + /** + * Now known for sure + */ + @SuppressWarnings("unused") + private boolean unselect; + + /** + * @param charService + * the character service + */ + @Inject + public CM_CHAR_TARGET_UNSELECT(CharacterService charService) { + this.charService = charService; + } + + @Override + public void read(Lineage2Client conn, ChannelBuffer buffer) { + this.unselect = (buffer.readByte() == 1 ? true : false); + } + + @Override + public void process(final Lineage2Client conn) { + try { + charService.target(conn.getCharacter(), null); + } catch (CannotSetTargetServiceException e) { + conn.sendSystemMessage(SystemMessage.FAILED_DISABLE_TARGET); + } + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_ENTER_WORLD.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_ENTER_WORLD.java new file mode 100644 index 000000000..50ce10d43 --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_ENTER_WORLD.java @@ -0,0 +1,96 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +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.model.id.object.CharacterID; +import com.l2jserver.service.game.character.CharacterService; +import com.l2jserver.service.game.spawn.AlreadySpawnedServiceException; +import com.l2jserver.service.game.spawn.SpawnPointNotFoundServiceException; +import com.l2jserver.service.network.model.Lineage2Client; +import com.l2jserver.service.network.model.packet.AbstractClientPacket; + +/** + * The client is requesting a logout. Currently, when this packet is received + * the connection is immediately closed. + * + * @author Rogiel + */ +public class CM_ENTER_WORLD extends AbstractClientPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0x03; + + /** + * The logger + */ + private final Logger log = LoggerFactory.getLogger(CM_ENTER_WORLD.class); + + /** + * The {@link CharacterService} + */ + private final CharacterService characterService; + + /** + * @param characterService + * the character service + */ + @Inject + public CM_ENTER_WORLD(CharacterService characterService) { + this.characterService = characterService; + } + + @Override + public void read(Lineage2Client conn, ChannelBuffer buffer) { + buffer.readBytes(new byte[32]); // Unknown Byte Array + buffer.readInt(); // Unknown Value + buffer.readInt(); // Unknown Value + buffer.readInt(); // Unknown Value + buffer.readInt(); // Unknown Value + buffer.readBytes(new byte[32]); // Unknown Byte Array + buffer.readInt(); // Unknown Value + // TODO parse tracert + // for (int i = 0; i < 5; i++) + // for (int o = 0; o < 4; o++) + // tracert[i][o] = readC(); + } + + @Override + public void process(final Lineage2Client conn) { + final CharacterID id = conn.getCharacterID(); + if (id == null) { + log.warn( + "Client {} is trying to enter world without select a character", + conn); + conn.close(); + return; + } + // TODO send fail message + try { + characterService.enterWorld(id.getObject()); + } catch (SpawnPointNotFoundServiceException e) { + conn.sendActionFailed(); + } catch (AlreadySpawnedServiceException e) { + // TODO send an error message here + } + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_EXT_REQ_ALL_FORTRESS_INFO.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_EXT_REQ_ALL_FORTRESS_INFO.java new file mode 100644 index 000000000..c6cdd64de --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_EXT_REQ_ALL_FORTRESS_INFO.java @@ -0,0 +1,48 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.packet.client; + +import org.jboss.netty.buffer.ChannelBuffer; + +import com.l2jserver.game.net.packet.server.SM_FORT_INFO; +import com.l2jserver.service.network.model.Lineage2Client; +import com.l2jserver.service.network.model.packet.AbstractClientPacket; + +/** + * The client is requesting the manor list. + * + * @author Rogiel + */ +public class CM_EXT_REQ_ALL_FORTRESS_INFO extends AbstractClientPacket { + /** + * The packet OPCODE1 + */ + public static final int OPCODE1 = 0xd0; + /** + * The packet OPCODE2 + */ + public static final int OPCODE2 = 0x3d; + + @Override + public void read(Lineage2Client conn, ChannelBuffer buffer) { + } + + @Override + public void process(final Lineage2Client conn) { + conn.write(new SM_FORT_INFO()); + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_EXT_REQ_KEY_MAPPING.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_EXT_REQ_KEY_MAPPING.java new file mode 100644 index 000000000..c0e826251 --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_EXT_REQ_KEY_MAPPING.java @@ -0,0 +1,47 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.packet.client; + +import org.jboss.netty.buffer.ChannelBuffer; + +import com.l2jserver.service.network.model.Lineage2Client; +import com.l2jserver.service.network.model.packet.AbstractClientPacket; + +/** + * The client is requesting a the key mappings. + * + * @author Rogiel + */ +public class CM_EXT_REQ_KEY_MAPPING extends AbstractClientPacket { + /** + * The packet OPCODE1 + */ + public static final int OPCODE1 = 0xd0; + /** + * The packet OPCODE2 + */ + public static final int OPCODE2 = 0x21; + + @Override + public void read(Lineage2Client conn, ChannelBuffer buffer) { + } + + @Override + public void process(final Lineage2Client conn) { + // TODO + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_EXT_REQ_MANOR_LIST.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_EXT_REQ_MANOR_LIST.java new file mode 100644 index 000000000..bc1cc56be --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_EXT_REQ_MANOR_LIST.java @@ -0,0 +1,49 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.packet.client; + +import org.jboss.netty.buffer.ChannelBuffer; + +import com.l2jserver.game.net.packet.server.SM_MANOR_LIST; +import com.l2jserver.service.network.model.Lineage2Client; +import com.l2jserver.service.network.model.packet.AbstractClientPacket; + +/** + * The client is requesting the manor list. + * + * @author Rogiel + */ +public class CM_EXT_REQ_MANOR_LIST extends AbstractClientPacket { + /** + * The packet OPCODE1 + */ + public static final int OPCODE1 = 0xd0; + /** + * The packet OPCODE2 + */ + public static final int OPCODE2 = 0x08; + + @Override + public void read(Lineage2Client conn, ChannelBuffer buffer) { + } + + @Override + public void process(final Lineage2Client conn) { + conn.write(new SM_MANOR_LIST("gludio", "dion", "giran", "oren", "aden", + "innadril", "goddard", "rune", "schuttgart")); + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_GG_KEY.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_GG_KEY.java new file mode 100644 index 000000000..db32b0cd1 --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_GG_KEY.java @@ -0,0 +1,86 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +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.service.network.gameguard.GameGuardService; +import com.l2jserver.service.network.model.Lineage2Client; +import com.l2jserver.service.network.model.packet.AbstractClientPacket; + +/** + * The client is requesting a logout. Currently, when this packet is received + * the connection is immediately closed. + * + * @author Rogiel + */ +public class CM_GG_KEY extends AbstractClientPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0xca; + + /** + * The logger + */ + private static final Logger log = LoggerFactory.getLogger(CM_GG_KEY.class); + + /** + * The {@link GameGuardService} + */ + private final GameGuardService ggService; + + /** + * The Game guard authentication key + */ + private byte[] key = new byte[8]; + + /** + * @param ggService + * the gameguard service + */ + @Inject + public CM_GG_KEY(GameGuardService ggService) { + this.ggService = ggService; + } + + @Override + public void read(Lineage2Client conn, ChannelBuffer buffer) { + byte[] part1 = buffer.readBytes(4).array(); + buffer.readInt(); + byte[] part2 = buffer.readBytes(4).array(); + + // create a single key array + System.arraycopy(part1, 0, key, 0, 4); + System.arraycopy(part2, 0, key, 4, 4); + } + + @Override + public void process(final Lineage2Client conn) { + log.debug("Received GG key"); + switch (ggService.key(conn, key)) { + case INVALID: + log.warn("Client {} sent an invalid GG key", conn); + // if key is invalid, disconnect client + conn.close(); + return; + } + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_GOTO_LOBBY.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_GOTO_LOBBY.java new file mode 100644 index 000000000..10fe80e4e --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_GOTO_LOBBY.java @@ -0,0 +1,71 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +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.world.L2Character; +import com.l2jserver.service.network.model.Lineage2Client; +import com.l2jserver.service.network.model.packet.AbstractClientPacket; + +/** + * Requests the list of characters to be displayed in the lobby. The list of + * characters is sent to the client. + * + * @author Rogiel + */ +public class CM_GOTO_LOBBY extends AbstractClientPacket { + /** + * The packet OPCODE1 + */ + public static final int OPCODE1 = 0xd0; + /** + * The packet OPCODE2 + */ + public static final int OPCODE2 = 0x36; + + /** + * The {@link CharacterDAO} implementation + */ + private final CharacterDAO characterDao; + + /** + * @param characterDao + * the character dao + */ + @Inject + public CM_GOTO_LOBBY(CharacterDAO characterDao) { + this.characterDao = characterDao; + } + + @Override + public void read(Lineage2Client conn, ChannelBuffer buffer) { + } + + @Override + public void process(final Lineage2Client conn) { + final List chars = characterDao.selectByAccount(conn + .getSession().getAccountID()); + conn.write(SM_CHAR_LIST.fromL2Session(conn.getSession(), + chars.toArray(new L2Character[chars.size()]))); + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_ITEM_DESTROY.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_ITEM_DESTROY.java new file mode 100644 index 000000000..f88d9c796 --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_ITEM_DESTROY.java @@ -0,0 +1,105 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.packet.client; + +import org.jboss.netty.buffer.ChannelBuffer; + +import com.google.inject.Inject; +import com.l2jserver.model.id.object.ItemID; +import com.l2jserver.model.id.object.provider.ItemIDProvider; +import com.l2jserver.model.world.Item; +import com.l2jserver.service.game.item.ItemService; +import com.l2jserver.service.game.item.NonStackableItemsServiceException; +import com.l2jserver.service.game.item.NotEnoughItemsServiceException; +import com.l2jserver.service.network.model.Lineage2Client; +import com.l2jserver.service.network.model.SystemMessage; +import com.l2jserver.service.network.model.packet.AbstractClientPacket; + +/** + * This packet drops items on the ground. + * + * @author Rogiel + */ +public class CM_ITEM_DESTROY extends AbstractClientPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0x60; + + /** + * The {@link ItemService} + */ + private final ItemService itemService; + /** + * The {@link ItemID} provider + */ + private final ItemIDProvider itemIdProvider; + + /** + * The item ID + */ + private int objectId; + /** + * The number of items to be dropped + */ + private long count; + + /** + * @param itemService + * the item service + * @param itemIdProvider + * the item id provider + */ + @Inject + public CM_ITEM_DESTROY(ItemService itemService, + ItemIDProvider itemIdProvider) { + this.itemService = itemService; + this.itemIdProvider = itemIdProvider; + } + + @Override + public void read(Lineage2Client conn, ChannelBuffer buffer) { + objectId = buffer.readInt(); + count = buffer.readLong(); + } + + @Override + public void process(final Lineage2Client conn) { + final ItemID id = itemIdProvider.resolveID(objectId); + final Item item = id.getObject(); + + if (item == null) { + conn.sendActionFailed(); + return; + } + if (!conn.getCharacterID().equals(item.getOwnerID())) { + conn.sendActionFailed(); + return; + } + + try { + if (itemService.destroy(item, count)) { + conn.removeInventoryItems(item); + } else { + conn.updateInventoryItems(item); + } + } catch (NotEnoughItemsServiceException + | NonStackableItemsServiceException e) { + conn.sendSystemMessage(SystemMessage.CANNOT_DISCARD_THIS_ITEM); + } + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_ITEM_DROP.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_ITEM_DROP.java new file mode 100644 index 000000000..4cf7be88f --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_ITEM_DROP.java @@ -0,0 +1,127 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.packet.client; + +import org.jboss.netty.buffer.ChannelBuffer; + +import com.google.inject.Inject; +import com.l2jserver.model.id.object.ItemID; +import com.l2jserver.model.id.object.provider.ItemIDProvider; +import com.l2jserver.model.world.Item; +import com.l2jserver.service.game.item.ItemAlreadyOnGroundServiceException; +import com.l2jserver.service.game.item.ItemService; +import com.l2jserver.service.game.item.NonStackableItemsServiceException; +import com.l2jserver.service.game.item.NotEnoughItemsServiceException; +import com.l2jserver.service.game.spawn.AlreadySpawnedServiceException; +import com.l2jserver.service.game.spawn.SpawnPointNotFoundServiceException; +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.Point3D; + +/** + * This packet drops items on the ground. + * + * @author Rogiel + */ +public class CM_ITEM_DROP extends AbstractClientPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0x17; + + /** + * The {@link ItemService} + */ + private final ItemService itemService; + /** + * The {@link ItemID} provider + */ + private final ItemIDProvider itemIdProvider; + + /** + * The item ID + */ + private int objectId; + /** + * The number of items to be dropped + */ + private long count; + /** + * The location to be dropped + */ + private Point3D point; + + /** + * @param itemService + * the item service + * @param itemIdProvider + * the item id provider + */ + @Inject + public CM_ITEM_DROP(ItemService itemService, ItemIDProvider itemIdProvider) { + this.itemService = itemService; + this.itemIdProvider = itemIdProvider; + } + + @Override + public void read(Lineage2Client conn, ChannelBuffer buffer) { + objectId = buffer.readInt(); + count = buffer.readLong(); + point = Point3D.fromXYZ(buffer.readInt(), buffer.readInt(), + buffer.readInt()); + } + + @Override + public void process(final Lineage2Client conn) { + final ItemID id = itemIdProvider.resolveID(objectId); + final Item item = id.getObject(); + + if (item == null) { + conn.sendActionFailed(); + return; + } + if (!conn.getCharacterID().equals(item.getOwnerID())) { + conn.sendActionFailed(); + return; + } + + try { + final Item dropped = itemService.drop(item, count, point, + conn.getCharacter()); + if (dropped.equals(item)) { + conn.removeInventoryItems(dropped); + } else { + conn.updateInventoryItems(item); + } + if (dropped.getCount() == 1) { + conn.sendSystemMessage(SystemMessage.YOU_DROPPED_S1, item + .getTemplate().getName()); + } else { + conn.sendSystemMessage(SystemMessage.DROPPED_S1_S2, item + .getTemplate().getName(), Long.toString(dropped + .getCount())); + } + } catch (ItemAlreadyOnGroundServiceException + | AlreadySpawnedServiceException + | SpawnPointNotFoundServiceException + | NotEnoughItemsServiceException + | NonStackableItemsServiceException e) { + conn.sendActionFailed(); + } + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_LOGOUT.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_LOGOUT.java new file mode 100644 index 000000000..d66f37d7b --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_LOGOUT.java @@ -0,0 +1,52 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.packet.client; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.l2jserver.service.network.model.Lineage2Client; +import com.l2jserver.service.network.model.packet.AbstractClientPacket; + +/** + * The client is requesting a logout. Currently, when this packet is received + * the connection is immediately closed. + * + * @author Rogiel + */ +public class CM_LOGOUT extends AbstractClientPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0x09; + + /** + * The logger + */ + private static final Logger log = LoggerFactory.getLogger(CM_LOGOUT.class); + + @Override + public void read(Lineage2Client conn, ChannelBuffer buffer) { + } + + @Override + public void process(final Lineage2Client conn) { + log.debug("Logging out client {}", conn); + conn.close(); + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_PROTOCOL_VERSION.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_PROTOCOL_VERSION.java new file mode 100644 index 000000000..1c1f0ef13 --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_PROTOCOL_VERSION.java @@ -0,0 +1,125 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.packet.client; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.channel.ChannelFuture; +import org.jboss.netty.channel.ChannelFutureListener; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.inject.Inject; +import com.l2jserver.L2JConstant; +import com.l2jserver.game.net.InterludeLineage2Client; +import com.l2jserver.game.net.packet.server.SM_KEY; +import com.l2jserver.service.network.keygen.BlowfishKeygenService; +import com.l2jserver.service.network.model.Lineage2Client; +import com.l2jserver.service.network.model.Lineage2CryptographyKey; +import com.l2jserver.service.network.model.ProtocolVersion; +import com.l2jserver.service.network.model.packet.AbstractClientPacket; + +/** + * In this packet the client is informing its protocol version. It is possible + * to do an test and refuse invalid protocol versions. After this packet, the + * messages received and sent are all encrypted, except for the encryptation key + * which is sent here. + * + * @author Rogiel + */ +public class CM_PROTOCOL_VERSION extends AbstractClientPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0x00; + + /** + * The logger + */ + private final Logger log = LoggerFactory + .getLogger(CM_PROTOCOL_VERSION.class); + + // services + /** + * The {@link BlowfishKeygenService} implementation. Use to generate + * cryptography keys. + */ + private final BlowfishKeygenService keygen; + + // packet + /** + * The client version of the protocol + */ + private ProtocolVersion version; + + /** + * @param keygen + * the keygen service + */ + @Inject + public CM_PROTOCOL_VERSION(BlowfishKeygenService keygen) { + this.keygen = keygen; + } + + @Override + public void read(Lineage2Client conn, ChannelBuffer buffer) { + this.version = ProtocolVersion.fromVersion((int) buffer + .readShort()); + } + + @Override + public void process(final Lineage2Client conn) { + // generate a new key + final Lineage2CryptographyKey inKey = new Lineage2CryptographyKey( + keygen.generate()); + + final InterludeLineage2Client client = (InterludeLineage2Client) conn; + + client.getDecrypter().enable(inKey); + final Lineage2CryptographyKey outKey = inKey.copy(); + log.debug("Decrypter has been enabled"); + + log.debug("Client protocol version: {}", version); + conn.setVersion(version); + if (L2JConstant.SUPPORTED_PROTOCOL != version) { + log.warn("Incorrect protocol version: {}. Only {} is supported.", + version, L2JConstant.SUPPORTED_PROTOCOL); + // notify wrong protocol and close connection + conn.write(new SM_KEY(inKey, false)).addListener( + new ChannelFutureListener() { + @Override + public void operationComplete(ChannelFuture future) + throws Exception { + // close connection + conn.close(); + } + }); + return; + } + // activate encrypter once packet has been sent. + conn.write(new SM_KEY(inKey, true)).addListener( + new ChannelFutureListener() { + @Override + public void operationComplete(ChannelFuture future) + throws Exception { + log.debug("Encrypter has been enabled"); + // enable encrypter + client.getEncrypter().setKey(outKey); + client.getEncrypter().setEnabled(true); + } + }); + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_REQUEST_CHAR_TEMPLATE.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_REQUEST_CHAR_TEMPLATE.java new file mode 100644 index 000000000..6f6bea807 --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_REQUEST_CHAR_TEMPLATE.java @@ -0,0 +1,92 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +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_CHAR_TEMPLATE; +import com.l2jserver.model.id.template.CharacterTemplateID; +import com.l2jserver.model.id.template.provider.CharacterTemplateIDProvider; +import com.l2jserver.model.template.CharacterTemplate; +import com.l2jserver.model.template.character.CharacterClass; +import com.l2jserver.service.network.model.Lineage2Client; +import com.l2jserver.service.network.model.packet.AbstractClientPacket; + +/** + * Requests the creation of a new Character. The list of character templates is + * sent to the client, meaning that the client is authorized to create + * characters. + * + * @author Rogiel + */ +public class CM_REQUEST_CHAR_TEMPLATE extends AbstractClientPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0x0e; + + /** + * List of {@link CharacterClass} templates sent to the client + */ + private static final CharacterClass[] TEMPLATE_CLASSES = { + CharacterClass.HUMAN_FIGHTER, CharacterClass.HUMAN_MYSTIC, + CharacterClass.ELVEN_FIGHTER, CharacterClass.ELVEN_MYSTIC, + CharacterClass.DARK_FIGHTER, CharacterClass.DARK_MYSTIC, + CharacterClass.ORC_FIGHTER, CharacterClass.ORC_MYSTIC, + CharacterClass.DWARVEN_FIGHTER, CharacterClass.MALE_SOLDIER, + CharacterClass.FEMALE_SOLDIER }; + + /** + * The logger + */ + private static final Logger log = LoggerFactory + .getLogger(CM_REQUEST_CHAR_TEMPLATE.class); + + /** + * The {@link CharacterTemplateID} factory + */ + private final CharacterTemplateIDProvider idFactory; + + /** + * @param idFactory + * the character template id provider + */ + @Inject + public CM_REQUEST_CHAR_TEMPLATE(CharacterTemplateIDProvider idFactory) { + this.idFactory = idFactory; + } + + @Override + public void read(Lineage2Client conn, ChannelBuffer buffer) { + } + + @Override + public void process(final Lineage2Client conn) { + log.debug("Requested character templates"); + + final CharacterTemplate[] templates = new CharacterTemplate[TEMPLATE_CLASSES.length]; + int i = 0; + for (final CharacterClass charClass : TEMPLATE_CLASSES) { + final CharacterTemplateID id = idFactory.resolveID(charClass.id); + templates[i++] = id.getTemplate(); + } + conn.write(new SM_CHAR_TEMPLATE(templates)); + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_RESTART.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_RESTART.java new file mode 100644 index 000000000..5218986cb --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/client/CM_RESTART.java @@ -0,0 +1,80 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +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_CHAR_LIST; +import com.l2jserver.game.net.packet.server.SM_CHAR_RESTART; +import com.l2jserver.model.dao.CharacterDAO; +import com.l2jserver.service.game.character.CharacterService; +import com.l2jserver.service.game.spawn.NotSpawnedServiceException; +import com.l2jserver.service.network.model.Lineage2Client; +import com.l2jserver.service.network.model.packet.AbstractClientPacket; + +/** + * Requests the list of characters to be displayed in the lobby. The list of + * characters is sent to the client. + * + * @author Rogiel + */ +public class CM_RESTART extends AbstractClientPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0x46; + + /** + * The {@link CharacterService} + */ + private final CharacterService charService; + /** + * The {@link CharacterDAO} + */ + private final CharacterDAO charDao; + + /** + * @param charService + * the character service + * @param charDao + * the character dao + */ + @Inject + public CM_RESTART(CharacterService charService, CharacterDAO charDao) { + this.charService = charService; + this.charDao = charDao; + } + + @Override + public void read(Lineage2Client conn, ChannelBuffer buffer) { + } + + @Override + public void process(final Lineage2Client conn) { + try { + charService.leaveWorld(conn.getCharacter()); + } catch (NotSpawnedServiceException e) { + conn.sendActionFailed(); + return; + } + conn.setCharacterID(null); + conn.write(SM_CHAR_RESTART.ok()); + conn.write(SM_CHAR_LIST.fromL2Session(conn.getSession(), + charDao.selectByAccount(conn.getSession().getAccountID()))); + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_ACTION_FAILED.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_ACTION_FAILED.java new file mode 100644 index 000000000..493fbc6e4 --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_ACTION_FAILED.java @@ -0,0 +1,50 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.packet.server; + +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 + * + * @author Rogiel + */ +public class SM_ACTION_FAILED extends AbstractServerPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0x25; + + /** + * The {@link SM_ACTION_FAILED} shared instance + */ + public static final SM_ACTION_FAILED SHARED_INSTANCE = new SM_ACTION_FAILED(); + + /** + * Creates a new instance + */ + public SM_ACTION_FAILED() { + super(OPCODE); + } + + @Override + public void write(Lineage2Client conn, ChannelBuffer buffer) { + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_ACTOR_ATTACK.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_ACTOR_ATTACK.java new file mode 100644 index 000000000..e120128d6 --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_ACTOR_ATTACK.java @@ -0,0 +1,114 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.packet.server; + +import java.util.Collections; +import java.util.List; + +import org.jboss.netty.buffer.ChannelBuffer; + +import com.l2jserver.model.server.AttackHit; +import com.l2jserver.model.world.Actor; +import com.l2jserver.service.network.model.Lineage2Client; +import com.l2jserver.service.network.model.packet.AbstractServerPacket; +import com.l2jserver.util.factory.CollectionFactory; + +/** + * This packet informs the client of an attack issued + * + * @author Rogiel + * @see AttackHit + */ +public class SM_ACTOR_ATTACK extends AbstractServerPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0x05; + + /** + * The attacker actor + */ + private final Actor attacker; + /** + * List of hits to be sent + */ + private final List hits = CollectionFactory.newList(); + + /** + * @param attacker + * the attacked + * @param hits + * the hits + */ + public SM_ACTOR_ATTACK(Actor attacker, AttackHit... hits) { + super(OPCODE); + this.attacker = attacker; + Collections.addAll(this.hits, hits); + } + + /** + * @param hits + * the hits + */ + public SM_ACTOR_ATTACK(AttackHit... hits) { + this(hits[0].getAttacker(), hits); + } + + @Override + public void write(Lineage2Client conn, ChannelBuffer buffer) { + buffer.writeInt(attacker.getID().getID()); + + final AttackHit first = hits.get(0); + buffer.writeInt(first.getTarget().getID().getID()); + buffer.writeInt((int) first.getDamage()); + buffer.writeByte(first.getFlagsByte()); + + buffer.writeInt(attacker.getPoint().getX()); + buffer.writeInt(attacker.getPoint().getY()); + buffer.writeInt(attacker.getPoint().getZ()); + + buffer.writeShort(hits.size() - 1); + if (hits.size() > 1) { + boolean skipFirst = false; + for (final AttackHit hit : hits) { + if (!skipFirst) { + skipFirst = true; + continue; + } + buffer.writeInt(hit.getTarget().getID().getID()); + buffer.writeInt((int) hit.getDamage()); + buffer.writeByte(hit.getFlagsByte()); + } + } + + buffer.writeInt(first.getTarget().getPoint().getX()); + buffer.writeInt(first.getTarget().getPoint().getY()); + buffer.writeInt(first.getTarget().getPoint().getZ()); + } + + /** + * Adds a new hit + * + * @param hit + * the hit + * @return this instance + */ + public SM_ACTOR_ATTACK add(AttackHit hit) { + hits.add(hit); + return this; + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_ACTOR_CHAT.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_ACTOR_CHAT.java new file mode 100644 index 000000000..c89149987 --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_ACTOR_CHAT.java @@ -0,0 +1,103 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.packet.server; + +import org.jboss.netty.buffer.ChannelBuffer; + +import com.l2jserver.model.world.Actor; +import com.l2jserver.model.world.L2Character; +import com.l2jserver.service.game.chat.ChatMessageType; +import com.l2jserver.service.network.model.Lineage2Client; +import com.l2jserver.service.network.model.packet.AbstractServerPacket; +import com.l2jserver.util.BufferUtils; + +/** + * This packet notifies the client that the chosen character has been + * successfully selected. + * + * @author Rogiel + */ +public class SM_ACTOR_CHAT extends AbstractServerPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0x4a; + + /** + * The sending actor + */ + private final Actor actor; + /** + * The message destination + */ + private ChatMessageType destination; + /** + * The message + */ + private String message = null; + /** + * The message ID + */ + private int messageID = 0; + + /** + * @param character + * the actor + * @param destination + * the destination + * @param message + * the message + */ + public SM_ACTOR_CHAT(Actor character, ChatMessageType destination, + String message) { + super(OPCODE); + this.actor = character; + this.destination = destination; + this.message = message; + } + + /** + * @param actor + * the actor + * @param destination + * the destination + * @param messageID + * the message id + */ + public SM_ACTOR_CHAT(Actor actor, ChatMessageType destination, int messageID) { + super(OPCODE); + this.actor = actor; + this.destination = destination; + this.messageID = messageID; + } + + @Override + public void write(Lineage2Client conn, ChannelBuffer buffer) { + buffer.writeInt(actor.getID().getID()); + buffer.writeInt(destination.id); + if (actor instanceof L2Character) { + BufferUtils.writeString(buffer, ((L2Character) actor).getName()); + } else { + buffer.writeInt(actor.getID().getID()); + } + if (message != null) { + BufferUtils.writeString(buffer, message); + } else { + buffer.writeInt(messageID); + } + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_ACTOR_DIE.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_ACTOR_DIE.java new file mode 100644 index 000000000..ead169c47 --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_ACTOR_DIE.java @@ -0,0 +1,62 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.packet.server; + +import org.jboss.netty.buffer.ChannelBuffer; + +import com.l2jserver.model.server.AttackHit; +import com.l2jserver.model.world.Actor; +import com.l2jserver.service.network.model.Lineage2Client; +import com.l2jserver.service.network.model.packet.AbstractServerPacket; + +/** + * This packet informs the client of an attack issued + * + * @author Rogiel + * @see AttackHit + */ +public class SM_ACTOR_DIE extends AbstractServerPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0x00; + + /** + * The attacker actor + */ + private final Actor actor; + + /** + * @param actor + * the actor + */ + public SM_ACTOR_DIE(Actor actor) { + super(OPCODE); + this.actor = actor; + } + + @Override + public void write(Lineage2Client conn, ChannelBuffer buffer) { + buffer.writeInt(actor.getID().getID()); + buffer.writeInt(0x00); // to hide away + buffer.writeInt(0x00); // to castle + buffer.writeInt(0x00); // to siege HQ + buffer.writeInt(0x00); // sweepable (blue glow) + buffer.writeInt(0x00); // to FIXED + buffer.writeInt(0x00); // to fortress + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_ACTOR_MOVE.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_ACTOR_MOVE.java new file mode 100644 index 000000000..0c433aa10 --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_ACTOR_MOVE.java @@ -0,0 +1,73 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.packet.server; + +import org.jboss.netty.buffer.ChannelBuffer; + +import com.l2jserver.model.world.Actor; +import com.l2jserver.service.network.model.Lineage2Client; +import com.l2jserver.service.network.model.packet.AbstractServerPacket; +import com.l2jserver.util.geometry.Coordinate; + +/** + * This packet notifies the client that the character is moving to an certain + * point. If the {@link Actor} moving is the same as the client connected, the + * client will send position validations at specific time intervals. + * + * @author Rogiel O + */ +public class SM_ACTOR_MOVE extends AbstractServerPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0x01; + + /** + * The selected character + */ + private final Actor actor; + /** + * The destination coordinate + */ + private Coordinate target; + + /** + * @param actor + * the actor + * @param target + * the target + */ + public SM_ACTOR_MOVE(Actor actor, Coordinate target) { + super(OPCODE); + this.actor = actor; + this.target = target; + } + + @Override + public void write(Lineage2Client conn, ChannelBuffer buffer) { + buffer.writeInt(actor.getID().getID()); + // target + buffer.writeInt(target.getX()); + buffer.writeInt(target.getY()); + buffer.writeInt(target.getZ()); + + // source + buffer.writeInt(actor.getPoint().getX()); + buffer.writeInt(actor.getPoint().getY()); + buffer.writeInt(actor.getPoint().getZ()); + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_ACTOR_POSITION.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_ACTOR_POSITION.java new file mode 100644 index 000000000..de035bbd1 --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_ACTOR_POSITION.java @@ -0,0 +1,59 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.packet.server; + +import org.jboss.netty.buffer.ChannelBuffer; + +import com.l2jserver.model.world.Actor; +import com.l2jserver.service.network.model.Lineage2Client; +import com.l2jserver.service.network.model.packet.AbstractServerPacket; + +/** + * This packet notifies the client that the chosen character has been + * successfully selected. + * + * @author Rogiel + */ +public class SM_ACTOR_POSITION extends AbstractServerPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0x79; + + /** + * The selected character + */ + private final Actor actor; + + /** + * @param actor + * the actor + */ + public SM_ACTOR_POSITION(Actor actor) { + super(OPCODE); + this.actor = actor; + } + + @Override + public void write(Lineage2Client conn, ChannelBuffer buffer) { + buffer.writeInt(actor.getID().getID()); + buffer.writeInt(actor.getPoint().getX()); + buffer.writeInt(actor.getPoint().getY()); + buffer.writeInt(actor.getPoint().getZ()); + buffer.writeInt((int) actor.getPoint().getAngle()); + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_ACTOR_STATUS_UPDATE.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_ACTOR_STATUS_UPDATE.java new file mode 100644 index 000000000..921131244 --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_ACTOR_STATUS_UPDATE.java @@ -0,0 +1,219 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.packet.server; + +import java.util.Map; +import java.util.Map.Entry; + +import org.jboss.netty.buffer.ChannelBuffer; + +import com.l2jserver.model.world.Actor; +import com.l2jserver.service.network.model.Lineage2Client; +import com.l2jserver.service.network.model.packet.AbstractServerPacket; +import com.l2jserver.util.factory.CollectionFactory; + +/** + * This packet notifies the client that the chosen character has been + * successfully selected. + * + * @author Rogiel + */ +public class SM_ACTOR_STATUS_UPDATE extends AbstractServerPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0x0e; + + /** + * The stats the can be updated with the packet + * + * @author Rogiel + */ + public enum Stat { + /** + * Updates the character level + */ + LEVEL(0x01), + /** + * Updates the character experience + */ + EXPERIENCE(0x02), + /** + * Updates the character strength + */ + STR(0x03), + /** + * Updates the character dexterity + */ + DEX(0x04), + + /** + * Updates the character concentration + */ + CON(0x05), + /** + * Updates the character intelligence + */ + INT(0x06), + /** + * Updates the character witness + */ + WIT(0x07), + /** + * Updates the character mentality + */ + MEN(0x08), + /** + * Updates the character hp + */ + HP(0x09), + /** + * Updates the character maximum hp + */ + MAX_HP(0x0a), + /** + * Updates the character hp + */ + MP(0x0b), + /** + * Updates the character maximum mp + */ + MAX_MP(0x0c), + /** + * Updates the character sp + */ + SP(0x0d), + /** + * Updates the character load + */ + LOAD(0x0e), + /** + * Updates the character maximum load + */ + MAX_LOAD(0x0f), + /** + * Updates the character physical attack + */ + PHYSICAL_ATK(0x11), + /** + * Updates the character attack speed + */ + ATTACK_SPEED(0x12), + /** + * Updates the character physical defense + */ + PHYSICAL_DEFENSE(0x13), + /** + * Updates the character evasion + */ + EVASION(0x14), + /** + * Updates the character accuracy + */ + ACCURACY(0x15), + /** + * Updates the character critical + */ + CRITICAL(0x16), + /** + * Updates the character magical attack + */ + MAGICAL_ATTACK(0x17), + /** + * Updates the character cast speed + */ + CAST_SPEED(0x18), + /** + * Updates the character magical defense + */ + MAGICAL_DEFENSE(0x19), + + /** + * Updates the character pvp flag + */ + PVP_FLAG(0x1a), + + /** + * Updates the character karma + */ + KARMA(0x1b), + + /** + * Updates the character cp + */ + CP(0x21), + + /** + * Updates the character max cp + */ + MAX_CP(0x22); + + /** + * The stat id + */ + public final int id; + + /** + * @param id + * the stat id + */ + Stat(int id) { + this.id = id; + } + } + + /** + * The set of updates to be sent + */ + private final Map update = CollectionFactory.newMap(); + /** + * The actor to be updated + */ + private final Actor actor; + + /** + * @param actor + * the actor + */ + public SM_ACTOR_STATUS_UPDATE(Actor actor) { + super(OPCODE); + this.actor = actor; + } + + @Override + public void write(Lineage2Client conn, ChannelBuffer buffer) { + buffer.writeInt(actor.getID().getID()); + buffer.writeInt(update.size()); + + for (Entry entry : update.entrySet()) { + buffer.writeInt(entry.getKey().id); + buffer.writeInt(entry.getValue()); + } + } + + /** + * @param stat + * the stat + * @param value + * the stat value + * @return this instances + */ + public SM_ACTOR_STATUS_UPDATE add(Stat stat, int value) { + update.put(stat, value); + return this; + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_CREATE_FAIL.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_CREATE_FAIL.java new file mode 100644 index 000000000..77fb450f7 --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_CREATE_FAIL.java @@ -0,0 +1,116 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.packet.server; + +import org.jboss.netty.buffer.ChannelBuffer; + +import com.l2jserver.service.network.model.Lineage2Client; +import com.l2jserver.service.network.model.packet.AbstractServerPacket; + +/** + * An packet informing that the character could not be created. + * + * @author Rogiel + * @see Reason + */ +public class SM_CHAR_CREATE_FAIL extends AbstractServerPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0x1A; + + /** + * The character creation failure reason + */ + private Reason reason; + + /** + * The character creation error reason + * + * @author Rogiel + */ + public enum Reason { + /** + * "Your character creation has failed." + */ + REASON_CREATION_FAILED(0x00), + /** + * "You cannot create another character. Please delete the existing + * character and try again." Removes all settings that were selected + * (race, class, etc)" + */ + REASON_TOO_MANY_CHARACTERS(0x01), + /** + * "This name already exists." + */ + REASON_NAME_ALREADY_EXISTS(0x02), + /** + * "Your title cannot exceed 16 characters in length. Please try again." + */ + REASON_16_ENG_CHARS(0x03), + /** + * "Incorrect name. Please try again." + */ + REASON_INCORRECT_NAME(0x04), + /** + * "Characters cannot be created from this server." + */ + REASON_CREATE_NOT_ALLOWED(0x05), + /** + * "Unable to create character. You are unable to create a new character + * on the selected server. A restriction is in place which restricts + * users from creating characters on different servers where no previous + * character exists. Please choose another server." + */ + REASON_CHOOSE_ANOTHER_SVR(0x06); + + /** + * The error code id + */ + public final int id; + + /** + * @param id + * the reason id + */ + Reason(int id) { + this.id = id; + } + + /** + * @return an {@link SM_CHAR_CREATE_FAIL} instance for this enum + * constant + */ + public SM_CHAR_CREATE_FAIL newInstance() { + return new SM_CHAR_CREATE_FAIL(this); + } + } + + /** + * @param reason + * the reason + */ + public SM_CHAR_CREATE_FAIL(Reason reason) { + super(OPCODE); + this.reason = reason; + } + + @Override + public void write(Lineage2Client conn, ChannelBuffer buffer) { + buffer.writeInt(reason.id); + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_CREATE_OK.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_CREATE_OK.java new file mode 100644 index 000000000..cf008fb5c --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_CREATE_OK.java @@ -0,0 +1,51 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.packet.server; + +import org.jboss.netty.buffer.ChannelBuffer; + +import com.l2jserver.service.network.model.Lineage2Client; +import com.l2jserver.service.network.model.packet.AbstractServerPacket; + +/** + * An packet informing that the character was created with success. + * + * @author Rogiel + */ +public class SM_CHAR_CREATE_OK extends AbstractServerPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0x19; + + /** + * The packet shared instance + */ + public static final SM_CHAR_CREATE_OK INSTANCE = new SM_CHAR_CREATE_OK(); + + /** + * Creates a new instance + */ + public SM_CHAR_CREATE_OK() { + super(OPCODE); + } + + @Override + public void write(Lineage2Client conn, ChannelBuffer buffer) { + buffer.writeInt(0x01); + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_ENTER_WORLD.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_ENTER_WORLD.java new file mode 100644 index 000000000..b6702b760 --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_ENTER_WORLD.java @@ -0,0 +1,104 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.packet.server; + +import org.jboss.netty.buffer.ChannelBuffer; + +import com.l2jserver.model.world.L2Character; +import com.l2jserver.model.world.actor.ActorExperience; +import com.l2jserver.service.network.model.Lineage2Client; +import com.l2jserver.service.network.model.packet.AbstractServerPacket; +import com.l2jserver.util.BufferUtils; + +/** + * An packet informing that the character was created with success. + * + * @author Rogiel + */ +public class SM_CHAR_ENTER_WORLD extends AbstractServerPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0x0b; + + /** + * The entering character + */ + private final L2Character character; + /** + * The session ID + */ + private final int sessionId; + + /** + * Creates a new instance + * + * @param character + * the character + * @param sessionId + * the session id + */ + public SM_CHAR_ENTER_WORLD(L2Character character, int sessionId) { + super(OPCODE); + this.character = character; + this.sessionId = sessionId; + } + + @Override + public void write(Lineage2Client conn, ChannelBuffer buffer) { + BufferUtils.writeString(buffer, character.getName()); + buffer.writeInt(character.getID().getID()); + BufferUtils.writeString(buffer, "Hello world!"); + buffer.writeInt(sessionId); + buffer.writeInt(0x00); // clan id + buffer.writeInt(0x00); // ?? + buffer.writeInt(character.getSex().option); + buffer.writeInt(character.getRace().id); + buffer.writeInt(character.getCharacterClass().id); + buffer.writeInt(0x01); // active ?? + buffer.writeInt(character.getPosition().getX()); + buffer.writeInt(character.getPosition().getY()); + buffer.writeInt(character.getPosition().getZ()); + + buffer.writeDouble(100); + buffer.writeDouble(100); + buffer.writeInt(0x00); + buffer.writeLong(ActorExperience.LEVEL_1.experience); + buffer.writeInt(ActorExperience.LEVEL_1.level); + buffer.writeInt(0x00); // karma + buffer.writeInt(0x00); // pk + buffer.writeInt(character.getStats().getIntelligence()); // INT + buffer.writeInt(character.getStats().getStrength()); // STR + buffer.writeInt(character.getStats().getConcentration()); // CON + buffer.writeInt(character.getStats().getMentality()); // MEN + buffer.writeInt(character.getStats().getDexterity()); // DEX + buffer.writeInt(character.getStats().getWitness()); // WIT + + buffer.writeInt(250); // game time + buffer.writeInt(0x00); + + buffer.writeInt(character.getCharacterClass().id); + + buffer.writeInt(0x00); + buffer.writeInt(0x00); + buffer.writeInt(0x00); + buffer.writeInt(0x00); + + buffer.writeBytes(new byte[64]); + buffer.writeInt(0x00); + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_INFO.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_INFO.java new file mode 100644 index 000000000..b9edb6122 --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_INFO.java @@ -0,0 +1,376 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.packet.server; + +import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.CHEST; +import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.CLOAK; +import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.FEET; +import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.GLOVES; +import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.HAIR1; +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.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.LEGS; +import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.NECK; +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.UNDERWEAR; + +import org.jboss.netty.buffer.ChannelBuffer; + +import com.l2jserver.model.template.actor.ActorSex; +import com.l2jserver.model.world.Item; +import com.l2jserver.model.world.L2Character; +import com.l2jserver.model.world.actor.ActorExperience; +import com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll; +import com.l2jserver.service.network.model.Lineage2Client; +import com.l2jserver.service.network.model.packet.AbstractServerPacket; +import com.l2jserver.util.BufferUtils; + +/** + * This is an message informing the client of an given player + * + *

+ * (c) dddddSddddQdddddddddddddddddddddddddddddddddddddddddddddddddd
+ * ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd
+ * fdfdfdfddddSdddddcccddh[h]cdcdhhdhddddccdcccddddcdddddhhhhhhhdddd
+ * d
+ * 
+ * + * @author Rogiel + */ +public class SM_CHAR_INFO extends AbstractServerPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0x04; + + /** + * The character + */ + private L2Character character; + + /** + * @param character + * the character + */ + public SM_CHAR_INFO(L2Character character) { + super(OPCODE); + this.character = character; + } + + @Override + public void write(Lineage2Client conn, ChannelBuffer buffer) { + buffer.writeInt(character.getPoint().getX()); + buffer.writeInt(character.getPoint().getY()); + buffer.writeInt(character.getPoint().getZ()); + buffer.writeInt((int)character.getPoint().getAngle()); + buffer.writeInt(character.getID().getID()); + BufferUtils.writeString(buffer, character.getName()); + buffer.writeInt(character.getRace().id); + buffer.writeInt(character.getSex().option); + + buffer.writeInt(character.getCharacterClass().id); + + buffer.writeInt(character.getLevel()); + buffer.writeLong(ActorExperience.LEVEL_1.experience); + buffer.writeInt(character.getStats().getStrength()); + buffer.writeInt(character.getStats().getDexterity()); + buffer.writeInt(character.getStats().getConcentration()); + buffer.writeInt(character.getStats().getIntelligence()); + buffer.writeInt(character.getStats().getWitness()); + buffer.writeInt(character.getStats().getMentality()); + buffer.writeInt(character.getStats().getMaxHP()); // max hp + buffer.writeInt((int) character.getHP()); // cur hp + buffer.writeInt(character.getStats().getMaxMP()); // max mp + buffer.writeInt((int) character.getMP()); // cur mp + buffer.writeInt(character.getSP()); // sp + buffer.writeInt(0); // max load + buffer.writeInt(character.getStats().getMaximumLoad()); // max load + + // 20 no weapon, 40 weapon equippe TODO + buffer.writeInt(20); + + writePaperdollObjectID(buffer, character, UNDERWEAR); + writePaperdollObjectID(buffer, character, RIGHT_EAR); + writePaperdollObjectID(buffer, character, LEFT_EAR); + writePaperdollObjectID(buffer, character, NECK); + writePaperdollObjectID(buffer, character, RIGHT_FINGER); + writePaperdollObjectID(buffer, character, LEFT_FINGER); + writePaperdollObjectID(buffer, character, HEAD); + writePaperdollObjectID(buffer, character, RIGHT_HAND); + writePaperdollObjectID(buffer, character, LEFT_HAND); + writePaperdollObjectID(buffer, character, GLOVES); + writePaperdollObjectID(buffer, character, CHEST); + writePaperdollObjectID(buffer, character, LEGS); + writePaperdollObjectID(buffer, character, FEET); + writePaperdollObjectID(buffer, character, CLOAK); + writePaperdollObjectID(buffer, character, RIGHT_HAND); + writePaperdollObjectID(buffer, character, HAIR1); + writePaperdollObjectID(buffer, character, HAIR2); + + writePaperdollItemID(buffer, character, UNDERWEAR); + 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); + + buffer.writeShort(0x00); + buffer.writeShort(0x00); + buffer.writeShort(0x00); + buffer.writeShort(0x00); + buffer.writeShort(0x00); + buffer.writeShort(0x00); + buffer.writeShort(0x00); + buffer.writeShort(0x00); + buffer.writeShort(0x00); + buffer.writeShort(0x00); + buffer.writeShort(0x00); + buffer.writeShort(0x00); + buffer.writeShort(0x00); + buffer.writeShort(0x00); + writePaperdollAugumentID(buffer, character, RIGHT_HAND); + buffer.writeShort(0x00); + buffer.writeShort(0x00); + buffer.writeShort(0x00); + buffer.writeShort(0x00); + buffer.writeShort(0x00); + buffer.writeShort(0x00); + buffer.writeShort(0x00); + buffer.writeShort(0x00); + buffer.writeShort(0x00); + buffer.writeShort(0x00); + buffer.writeShort(0x00); + buffer.writeShort(0x00); + writePaperdollAugumentID(buffer, character, RIGHT_HAND); + buffer.writeShort(0x00); + buffer.writeShort(0x00); + buffer.writeShort(0x00); + buffer.writeShort(0x00); + + buffer.writeInt(character.getStats().getPhysicalAttack()); + buffer.writeInt(character.getStats().getPhysicalAttackSpeed()); + buffer.writeInt(character.getStats().getPhysicalDefense()); + + buffer.writeInt(character.getStats().getEvasionRate()); // evasion + buffer.writeInt(character.getStats().getAccuracy()); + buffer.writeInt(character.getStats().getPhysicalCriticalRate()); + + buffer.writeInt(character.getStats().getMagicalAttack()); + buffer.writeInt(character.getStats().getMagicalAttackSpeed()); + buffer.writeInt(character.getStats().getPhysicalAttackSpeed()); + buffer.writeInt(character.getStats().getMagicalDefense()); + + buffer.writeInt(0x00); // 0-non-pvp 1-pvp = violett name + buffer.writeInt(character.getKarma()); // karma + + buffer.writeInt(character.getStats().getRunSpeed()); + buffer.writeInt(character.getStats().getWalkSpeed()); + buffer.writeInt(character.getStats().getRunSpeed()); // runspeed in water TODO + buffer.writeInt(character.getStats().getWalkSpeed()); //walkspeed in water TODO + buffer.writeInt(0); // unk + buffer.writeInt(0); // unk + buffer.writeInt(0); // fly speed -only if flying + buffer.writeInt(0); // fly speed -only if flying + buffer.writeDouble(0x01); // move speed multiplier + buffer.writeDouble(0x01); // attack speed multiplier + + // L2Summon pet = _activeChar.getPet(); + // L2Transformation trans; + // if (_activeChar.getMountType() != 0 && pet != null) { + // writeF(pet.getTemplate().fCollisionRadius); + // writeF(pet.getTemplate().fCollisionHeight); + // } else if ((trans = _activeChar.getTransformation()) != null) { + // writeF(trans.getCollisionRadius()); + // writeF(trans.getCollisionHeight()); + // } else { + // writeF(_activeChar.getCollisionRadius()); + // writeF(_activeChar.getCollisionHeight()); + // } + if (character.getSex() == ActorSex.MALE) { + buffer.writeDouble(character.getTemplate().getCollision().getMale() + .getRadius()); + buffer.writeDouble(character.getTemplate().getCollision().getMale() + .getHeigth()); + } else { + buffer.writeDouble(character.getTemplate().getCollision() + .getFemale().getRadius()); + buffer.writeDouble(character.getTemplate().getCollision() + .getFemale().getHeigth()); + } + + buffer.writeInt(character.getAppearance().getHairStyle().option); + buffer.writeInt(character.getAppearance().getHairColor().option); + buffer.writeInt(character.getAppearance().getFace().option); + buffer.writeInt(0x01); // is gm + + BufferUtils.writeString(buffer, character.getTitle()); + + buffer.writeInt((character.getClanID() != null ? character.getClanID() + .getID() : 0x00)); // clanid + buffer.writeInt(0x00); // clan crest id + buffer.writeInt(0x00); // ally id + buffer.writeInt(0x00); // ally crest id + // 0x40 leader rights + // siege flags: attacker - 0x180 sword over name, defender - 0x80 + // shield, 0xC0 crown (|leader), 0x1C0 flag (|leader) + buffer.writeInt(0x40); //relation?? + buffer.writeByte(0x00); // mount type + buffer.writeByte(0x00); // private store type + buffer.writeByte(0x00); // dwarven craft + buffer.writeInt(character.getPkKills()); // pk kills + buffer.writeInt(character.getPvpKills()); // pvp kills + + buffer.writeShort(0x00); // cubics size + // short:cubicsid[cubicssize] + // buffer.writeShort(cubicid); + + buffer.writeByte(0); // is party match room + + buffer.writeInt(0x00); // abnormal effect + buffer.writeByte(0x0); // flying mounted = 2; otherwise: 0 + + buffer.writeInt(0x00); // clan privileges + + buffer.writeShort(2); // c2 recommendations remaining + buffer.writeShort(1); // c2 recommendations received + buffer.writeInt(0); // mount npc id + buffer.writeShort(500); // inventory limit + + buffer.writeInt(character.getCharacterClass().id); + buffer.writeInt(0x00); // special effects? circles around player... + buffer.writeInt(character.getStats().getMaxCP()); + buffer.writeInt((int) character.getCP()); // cur cp + buffer.writeByte(0x00); // is mount or is airshilhelp = 0; otherwise + // enchant effect (minimum 127) + + buffer.writeByte(0x00);// team, 1=blue,2 red,0 is unknown + + buffer.writeInt(0x00); // clan crest large id + // 0x01: symbol on char menu ctrl+I + buffer.writeByte(0x00); // is noble + buffer.writeByte(0x00); // 0x01: Hero Aura + + buffer.writeByte(0x00); // Fishing Mode + buffer.writeInt(0x00); // fishing x + buffer.writeInt(0x00); // fishing y + buffer.writeInt(0x00); // fishing z + buffer.writeInt(character.getAppearance().getNameColor().toInteger()); + + // new c5 + // is running + buffer.writeByte(character.getMoveType().id); + + // pledge class + buffer.writeInt(0x00); // changes the text above + // CP on Status Window + buffer.writeInt(0x00); // pledge type + + buffer.writeInt(character.getAppearance().getTitleColor().toInteger()); + + // cursed weapon ID equipped + buffer.writeInt(0x00); + +// // T1 Starts +// buffer.writeInt(0x00); // transformation id +// +// buffer.writeShort(0x00); // attack element +// buffer.writeShort(0x10); // attack element value +// buffer.writeShort(0x10); // fire defense value +// buffer.writeShort(0x10); // water def value +// buffer.writeShort(0x10); // wind def value +// buffer.writeShort(0x10); // earth def value +// buffer.writeShort(0x10); // holy def value +// buffer.writeShort(0x10); // dark def value +// +// buffer.writeInt(0x00); // getAgathionId +// +// // T2 Starts +// buffer.writeInt(0x00); // Fame +// buffer.writeInt(0x01); // Minimap on Hellbound +// buffer.writeInt(1); // Vitality Points +// buffer.writeInt(0x00); // special effects + } + + /** + * Writes the paperdoll object id + * + * @param buffer + * the buffer + * @param character + * the character + * @param paperdoll + * the slot + */ + private void writePaperdollObjectID(ChannelBuffer buffer, + L2Character character, InventoryPaperdoll paperdoll) { + final Item item = character.getInventory().getItem(paperdoll); + int id = 0; + if (item != null) + id = item.getID().getID(); + buffer.writeInt(id); + } + + /** + * Writes the paperdoll item id + * + * @param buffer + * the buffer + * @param character + * the character + * @param paperdoll + * the slot + */ + private void writePaperdollItemID(ChannelBuffer buffer, + L2Character character, InventoryPaperdoll paperdoll) { + final Item item = character.getInventory().getItem(paperdoll); + int id = 0; + if (item != null) + id = item.getTemplateID().getID(); + buffer.writeInt(id); + } + + /** + * Writes the paperdoll augument id + * + * @param buffer + * the buffer + * @param character + * the character + * @param paperdoll + * the slot + */ + private void writePaperdollAugumentID(ChannelBuffer buffer, + L2Character character, InventoryPaperdoll paperdoll) { + buffer.writeInt(0x00); + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_INFO_BROADCAST.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_INFO_BROADCAST.java new file mode 100644 index 000000000..9dbbb647a --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_INFO_BROADCAST.java @@ -0,0 +1,293 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.packet.server; + +import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.BELT; +import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.CHEST; +import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.CLOAK; +import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.DECORATION_1; +import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.DECORATION_2; +import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.DECORATION_3; +import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.DECORATION_4; +import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.DECORATION_5; +import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.DECORATION_6; +import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.FEET; +import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.GLOVES; +import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.HAIR1; +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.LEFT_BRACELET; +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.RIGHT_BRACELET; +import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.RIGHT_HAND; +import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.UNDERWEAR; + +import org.jboss.netty.buffer.ChannelBuffer; + +import com.l2jserver.model.template.actor.ActorSex; +import com.l2jserver.model.world.Item; +import com.l2jserver.model.world.L2Character; +import com.l2jserver.model.world.L2Character.CharacterMoveType; +import com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll; +import com.l2jserver.service.network.model.Lineage2Client; +import com.l2jserver.service.network.model.packet.AbstractServerPacket; +import com.l2jserver.util.BufferUtils; + +/** + * This packet sends to the client an actor information about an actor + * + * @author Rogiel + */ +public class SM_CHAR_INFO_BROADCAST extends AbstractServerPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0x31; + + /** + * The character + */ + private final L2Character character; + + /** + * @param character + * the character + */ + public SM_CHAR_INFO_BROADCAST(L2Character character) { + super(OPCODE); + this.character = character; + } + + @Override + public void write(Lineage2Client conn, ChannelBuffer buffer) { + buffer.writeInt(character.getPoint().getX()); + buffer.writeInt(character.getPoint().getY()); + buffer.writeInt(character.getPoint().getZ()); + buffer.writeInt(0x00); // unk + buffer.writeInt(character.getID().getID()); + BufferUtils.writeString(buffer, character.getName()); + buffer.writeInt(character.getRace().id); + buffer.writeInt(character.getSex().option); + + buffer.writeInt(character.getCharacterClass().id); + + writePaperdollItemID(buffer, character, UNDERWEAR); + // 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); + writePaperdollItemID(buffer, character, RIGHT_BRACELET); + writePaperdollItemID(buffer, character, LEFT_BRACELET); + writePaperdollItemID(buffer, character, DECORATION_1); + writePaperdollItemID(buffer, character, DECORATION_2); + writePaperdollItemID(buffer, character, DECORATION_3); + writePaperdollItemID(buffer, character, DECORATION_4); + writePaperdollItemID(buffer, character, DECORATION_5); + writePaperdollItemID(buffer, character, DECORATION_6); + writePaperdollItemID(buffer, character, BELT); + + writePaperdollAugumentID(buffer, character, UNDERWEAR); + // writePaperdollAugumentID(buffer, character, RIGHT_EAR); + // writePaperdollAugumentID(buffer, character, LEFT_EAR); + // writePaperdollAugumentID(buffer, character, NECK); + // writePaperdollAugumentID(buffer, character, RIGHT_FINGER); + // writePaperdollAugumentID(buffer, character, LEFT_FINGER); + writePaperdollAugumentID(buffer, character, HEAD); + writePaperdollAugumentID(buffer, character, RIGHT_HAND); + writePaperdollAugumentID(buffer, character, LEFT_HAND); + writePaperdollAugumentID(buffer, character, GLOVES); + writePaperdollAugumentID(buffer, character, CHEST); + writePaperdollAugumentID(buffer, character, LEGS); + writePaperdollAugumentID(buffer, character, FEET); + writePaperdollAugumentID(buffer, character, CLOAK); + writePaperdollAugumentID(buffer, character, RIGHT_HAND); + writePaperdollAugumentID(buffer, character, HAIR1); + writePaperdollAugumentID(buffer, character, HAIR2); + writePaperdollAugumentID(buffer, character, RIGHT_BRACELET); + writePaperdollAugumentID(buffer, character, LEFT_BRACELET); + writePaperdollAugumentID(buffer, character, DECORATION_1); + writePaperdollAugumentID(buffer, character, DECORATION_2); + writePaperdollAugumentID(buffer, character, DECORATION_3); + writePaperdollAugumentID(buffer, character, DECORATION_4); + writePaperdollAugumentID(buffer, character, DECORATION_5); + writePaperdollAugumentID(buffer, character, DECORATION_6); + writePaperdollAugumentID(buffer, character, BELT); + + buffer.writeInt(0x00); // unk + buffer.writeInt(0x01); // unk + // end of t1 new h's + + buffer.writeInt(0x00); // pvp flag + buffer.writeInt(character.getKarma()); // karma + + buffer.writeInt(character.getStats().getMagicalAttackSpeed()); + buffer.writeInt(character.getStats().getPhysicalAttackSpeed()); + + buffer.writeInt(0x00); // unk + + // FIXME half of those are walk speed + buffer.writeInt(character.getStats().getRunSpeed()); + buffer.writeInt(character.getStats().getRunSpeed()); + buffer.writeInt(character.getStats().getRunSpeed()); + buffer.writeInt(character.getStats().getRunSpeed()); + buffer.writeInt(character.getStats().getRunSpeed()); + buffer.writeInt(character.getStats().getRunSpeed()); + buffer.writeInt(character.getStats().getRunSpeed()); + buffer.writeInt(character.getStats().getRunSpeed()); + + buffer.writeDouble(0x01); // move speed multiplier + buffer.writeDouble(0x01); // attack speed multiplier + + if (character.getSex() == ActorSex.MALE) { + buffer.writeDouble(character.getTemplate().getCollision().getMale() + .getRadius()); + buffer.writeDouble(character.getTemplate().getCollision().getMale() + .getHeigth()); + } else { + buffer.writeDouble(character.getTemplate().getCollision() + .getFemale().getRadius()); + buffer.writeDouble(character.getTemplate().getCollision() + .getFemale().getHeigth()); + } + + buffer.writeInt(character.getAppearance().getHairStyle().option); + buffer.writeInt(character.getAppearance().getHairColor().option); + buffer.writeInt(character.getAppearance().getFace().option); + + BufferUtils.writeString(buffer, character.getTitle()); + + // dont send those 4 if using cursed weapon + buffer.writeInt(0); // clan id + buffer.writeInt(0); // crest id + buffer.writeInt(0); // ally id + buffer.writeInt(0); // ally crest id + + buffer.writeByte(0x01); // sitting + buffer.writeByte((character.getMoveType() == CharacterMoveType.RUN ? 0x01 + : 0x00)); + buffer.writeByte((character.isAttacking() ? 0x01 : 0x00)); // is in + // combat + + buffer.writeByte(0x00); // alike dead + + buffer.writeByte((character.getAppearance().isVisible() ? 0x00 : 0x01)); + + // 1-on Strider, 2-on Wyvern, + // 3-on Great Wolf, 0-no mount + buffer.writeByte(0x00); + buffer.writeByte(0x00); // 1 - sellshop + + // writeH(_activeChar.getCubics().size()); + // for (int id : _activeChar.getCubics().keySet()) + // writeH(id); + buffer.writeShort(0x00); // cubics size + + buffer.writeByte(0x00); // in party match room + buffer.writeInt(0x00); // abnormal + buffer.writeByte(0x00); // flying mounted + + // recom have + buffer.writeShort(0x00); // Blue value for name (0 = + // white, 255 = pure blue) + buffer.writeInt(1000000); // mount npc + buffer.writeInt(character.getCharacterClass().id); + buffer.writeInt(0x00); // ? + buffer.writeByte(0x00); // enchant effect + + buffer.writeByte(0x00); // team circle around feet 1= Blue, 2 = red + + buffer.writeInt(0x00); // clan crest large id + buffer.writeByte(0x00); // is noble - Symbol on char menu + // ctrl+I + buffer.writeByte(0x00); // Hero Aura + + // (Cant be undone by setting back to 0) + buffer.writeByte(0x00); // 0x01: Fishing Mode + buffer.writeInt(0x00); // fish x + buffer.writeInt(0x00);// fish y + buffer.writeInt(0x00); // fish z + + buffer.writeInt(character.getAppearance().getNameColor().toInteger()); + + buffer.writeInt((int) character.getPoint().getAngle()); + + buffer.writeInt(0x00); // pledge class + buffer.writeInt(0x00); // pledge type + + buffer.writeInt(character.getAppearance().getTitleColor().toInteger()); + + buffer.writeInt(0x00); // cursed weapon id + buffer.writeInt(0x00); // clan reputation + + // T1 + buffer.writeInt(0x00); // transformation id + buffer.writeInt(0x00); // agathion id + + // T2 + buffer.writeInt(0x01); // unk + + // T2.3 + buffer.writeInt(0x00); // special effect + } + + /** + * Writes the paperdoll item id + * + * @param buffer + * the buffer + * @param character + * the character + * @param paperdoll + * the slot + */ + private void writePaperdollItemID(ChannelBuffer buffer, + L2Character character, InventoryPaperdoll paperdoll) { + final Item item = character.getInventory().getItem(paperdoll); + int id = 0; + if (item != null) + id = item.getTemplateID().getID(); + buffer.writeInt(id); + } + + /** + * Writes the paperdoll augument id + * + * @param buffer + * the buffer + * @param character + * the character + * @param paperdoll + * the slot + */ + private void writePaperdollAugumentID(ChannelBuffer buffer, + L2Character character, InventoryPaperdoll paperdoll) { + buffer.writeInt(0x00); + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_INFO_EXTRA.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_INFO_EXTRA.java new file mode 100644 index 000000000..d4a6368a7 --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_INFO_EXTRA.java @@ -0,0 +1,60 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.packet.server; + +import org.jboss.netty.buffer.ChannelBuffer; + +import com.l2jserver.model.world.L2Character; +import com.l2jserver.service.network.model.Lineage2Client; +import com.l2jserver.service.network.model.packet.AbstractServerPacket; + +/** + * This is an message informing the client of extra informations from a player + * + * @author Rogiel + */ +public class SM_CHAR_INFO_EXTRA extends AbstractServerPacket { + /** + * The packet OPCODE1 + */ + public static final int OPCODE1 = 0xfe; + /** + * The packet OPCODE2 + */ + public static final int OPCODE2 = 0xcf; + + /** + * The character + */ + private L2Character character; + + /** + * @param character + * the character + */ + public SM_CHAR_INFO_EXTRA(L2Character character) { + super(OPCODE1); + this.character = character; + } + + @Override + public void write(Lineage2Client conn, ChannelBuffer buffer) { + buffer.writeShort(OPCODE2); // opcode2 + buffer.writeInt(character.getID().getID()); // object ID of Player + buffer.writeInt(0x00); // event effect id + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_INVENTORY.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_INVENTORY.java new file mode 100644 index 000000000..9150b20ad --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_INVENTORY.java @@ -0,0 +1,80 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.packet.server; + +import org.jboss.netty.buffer.ChannelBuffer; + +import com.l2jserver.model.world.Item; +import com.l2jserver.model.world.character.CharacterInventory; +import com.l2jserver.model.world.character.CharacterInventory.ItemLocation; +import com.l2jserver.service.network.model.Lineage2Client; +import com.l2jserver.service.network.model.packet.AbstractServerPacket; + +/** + * This packet send the inventory to the client + * + * @author Rogiel + */ +public class SM_CHAR_INVENTORY extends AbstractServerPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0x1b; + + /** + * The character inventory + */ + private CharacterInventory inventory; + /** + * Whether or not to open the inventory window + */ + private boolean showWindow = false; + + /** + * @param inventory + * the inventory + */ + public SM_CHAR_INVENTORY(CharacterInventory inventory) { + super(OPCODE); + this.inventory = inventory; + } + + @Override + public void write(Lineage2Client conn, ChannelBuffer buffer) { + buffer.writeShort((showWindow ? 0x01 : 0x00)); + // TODO warehouse items will have an issue here! + buffer.writeShort(inventory.getItemCount()); // item count + + for (Item item : inventory) { + buffer.writeShort(0x00); // "item type1" - whatever that is. check l2j TODO + buffer.writeInt(item.getID().getID()); // obj id + buffer.writeInt(item.getTemplateID().getID()); // item id + //buffer.writeInt(slot); // loc slot + buffer.writeLong(item.getCount()); // count + buffer.writeShort(0x00); // item type2 + buffer.writeShort(0x00); // item type3 + buffer.writeShort((item.getLocation() == ItemLocation.PAPERDOLL ? 0x01 + : 0x00)); // equiped? + buffer.writeInt((item.getPaperdoll() != null ? item.getPaperdoll().id + : 0)); // body part + buffer.writeShort(127); // enchant level + // race tickets + buffer.writeInt(0x00); // AugmentationId TODO + buffer.writeInt(0x00); // Remaining shadow item time TODO + } + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_INVENTORY_UPDATE.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_INVENTORY_UPDATE.java new file mode 100644 index 000000000..e1eab7723 --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_INVENTORY_UPDATE.java @@ -0,0 +1,226 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.packet.server; + +import java.util.Map; +import java.util.Map.Entry; + +import org.jboss.netty.buffer.ChannelBuffer; + +import com.l2jserver.model.world.Item; +import com.l2jserver.model.world.character.CharacterInventory.ItemLocation; +import com.l2jserver.service.network.model.Lineage2Client; +import com.l2jserver.service.network.model.packet.AbstractServerPacket; +import com.l2jserver.util.factory.CollectionFactory; + +/** + * This packet send the inventory to the client + * + * @author Rogiel + */ +public class SM_CHAR_INVENTORY_UPDATE extends AbstractServerPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0x27; + + /** + * List of items to be updated in the client + */ + private final Map items = CollectionFactory + .newMap(); + + /** + * The type of operation to be performed. + * + * @author Rogiel + */ + public enum InventoryUpdateType { + /** + * Flags the item to be added to the inventory list + */ + ADD(1), + /** + * Flags the item to be updated in the inventory list + */ + UPDATE(2), + /** + * Flags the item to be removed in the inventory list + */ + REMOVE(3); + + /** + * The operation ID + */ + public final int id; + + /** + * @param id + * the operation ID + */ + private InventoryUpdateType(int id) { + this.id = id; + } + } + + /** + * Creates an empty instance. Items can be added, removed or update using + * {@link #add(Item)}, {@link #remove(Item)} and {@link #update(Item)}. + */ + public SM_CHAR_INVENTORY_UPDATE() { + super(OPCODE); + } + + /** + * Creates a new instance with several items performing + * {@link InventoryUpdateType} type operation. + * + * @param type + * the operation type + * @param items + * the items + */ + public SM_CHAR_INVENTORY_UPDATE(InventoryUpdateType type, Item... items) { + super(OPCODE); + switch (type) { + case ADD: + add(items); + break; + case REMOVE: + remove(items); + break; + case UPDATE: + update(items); + break; + } + } + + @Override + public void write(Lineage2Client conn, ChannelBuffer buffer) { + buffer.writeShort(items.size()); // item count + + for (Entry e : items.entrySet()) { + final Item item = e.getKey(); + final InventoryUpdateType type = e.getValue(); + + buffer.writeShort(type.id); // change type + buffer.writeInt(item.getID().getID()); // obj id + buffer.writeInt(item.getTemplateID().getID()); // item id + buffer.writeInt(0x00); // loc slot + buffer.writeLong(item.getCount()); // count + buffer.writeShort(0x00); // item type2 + buffer.writeShort(0x00); // item type3 + buffer.writeShort((item.getLocation() == ItemLocation.PAPERDOLL ? 0x01 + : 0x00)); // equiped? + buffer.writeInt((item.getPaperdoll() != null ? item.getPaperdoll().id + : 0)); // body part + buffer.writeShort(127); // enchant level + // race tickets + buffer.writeShort(0x00); // item type4 (custom type 2) + buffer.writeInt(0x00); // augument + buffer.writeInt(0x00); // mana +// buffer.writeInt(-9999); // time +// 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); + } + } + + /** + * Removes a single item + * + * @param item + * the item to be removed + * @return this instance + */ + public SM_CHAR_INVENTORY_UPDATE remove(Item item) { + items.put(item, InventoryUpdateType.REMOVE); + return this; + } + + /** + * Removes several items + * + * @param items + * the items to be removed + * @return this instance + */ + public SM_CHAR_INVENTORY_UPDATE remove(Item... items) { + for (final Item item : items) { + remove(item); + } + return this; + } + + /** + * Adds a single item + * + * @param item + * the item to be added + * @return this instance + */ + public SM_CHAR_INVENTORY_UPDATE add(Item item) { + items.put(item, InventoryUpdateType.ADD); + return this; + } + + /** + * Adds several items + * + * @param items + * the item to be added + * @return this instance + */ + public SM_CHAR_INVENTORY_UPDATE add(Item... items) { + for (final Item item : items) { + add(item); + } + return this; + } + + /** + * Updates a single item + * + * @param item + * the item to be updated + * @return this instance + */ + public SM_CHAR_INVENTORY_UPDATE update(Item item) { + items.put(item, InventoryUpdateType.UPDATE); + return this; + } + + /** + * Updates several items + * + * @param items + * the item to be updated + * @return this instance + */ + public SM_CHAR_INVENTORY_UPDATE update(Item... items) { + for (final Item item : items) { + update(item); + } + return this; + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_LIST.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_LIST.java new file mode 100644 index 000000000..c268fd3e1 --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_LIST.java @@ -0,0 +1,241 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.packet.server; + +import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.CHEST; +import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.CLOAK; +import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.FEET; +import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.GLOVES; +import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.HAIR1; +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.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.LEGS; +import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.NECK; +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 java.util.Collection; + +import org.jboss.netty.buffer.ChannelBuffer; + +import com.l2jserver.model.world.Item; +import com.l2jserver.model.world.L2Character; +import com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll; +import com.l2jserver.service.network.model.Lineage2Client; +import com.l2jserver.service.network.model.Lineage2Session; +import com.l2jserver.service.network.model.packet.AbstractServerPacket; +import com.l2jserver.util.BufferUtils; + +/** + * The list of characters sent to the client. + * + * @author Rogiel + */ +public class SM_CHAR_LIST extends AbstractServerPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0x13; + + /** + * The account username + */ + private final String loginName; + /** + * The session ID + */ + private final int sessionId; + // private int lastCharacterId; + /** + * The list of character to be displayed + */ + private final L2Character[] characters; + + /** + * @param loginName + * the account id + * @param sessionId + * the session id + * @param lastCharacterId + * the last character used + * @param characters + * the characters + */ + public SM_CHAR_LIST(String loginName, int sessionId, int lastCharacterId, + L2Character... characters) { + super(OPCODE); + this.loginName = loginName; + this.sessionId = sessionId; + // this.lastCharacterId = lastCharacterId; + this.characters = characters; + } + + /** + * @param session + * the session + * @param characters + * the characters + * @return an {@link SM_CHAR_LIST} instance + */ + public static SM_CHAR_LIST fromL2Session(Lineage2Session session, + L2Character... characters) { + return new SM_CHAR_LIST(session.getAccountID().getID(), + session.getPlayKey2(), -1, characters); + } + + /** + * @param session + * the session + * @param characters + * the characters + * @return an {@link SM_CHAR_LIST} instance + */ + public static SM_CHAR_LIST fromL2Session(Lineage2Session session, + Collection characters) { + return fromL2Session(session, + characters.toArray(new L2Character[characters.size()])); + } + + @Override + public void write(Lineage2Client conn, ChannelBuffer buffer) { + buffer.writeInt(characters.length); + for ( final L2Character character : characters ) + { + BufferUtils.writeString(buffer, character.getName()); + buffer.writeInt(character.getID().getID()); + BufferUtils.writeString(buffer, loginName); + buffer.writeInt(sessionId); + buffer.writeInt((character.getClanID() != null ? character.getClanID().getID() : 0x01)); + buffer.writeInt(0x00); + + buffer.writeInt(character.getSex().option); + buffer.writeInt(character.getRace().id); + + buffer.writeInt(character.getCharacterClass().id); + + buffer.writeInt(0x01); + + buffer.writeInt(character.getPoint().getX()); // x + buffer.writeInt(character.getPoint().getY()); // y + buffer.writeInt(character.getPoint().getZ()); // z + + buffer.writeDouble(character.getHP()); // hp cur + buffer.writeDouble(character.getMP()); // mp cur + + buffer.writeInt(character.getSP()); // sp + buffer.writeLong(character.getExperience()); // exp + buffer.writeInt(character.getLevel()); // level + + buffer.writeInt(character.getKarma()); // karma + + buffer.writeInt(0x00); + buffer.writeInt(0x00); + buffer.writeInt(0x00); + buffer.writeInt(0x00); + buffer.writeInt(0x00); + buffer.writeInt(0x00); + buffer.writeInt(0x00); + buffer.writeInt(0x00); + buffer.writeInt(0x00); + + 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); + + // 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 + buffer.writeInt(character.getAppearance().getHairStyle().option); + // hair color + buffer.writeInt(character.getAppearance().getHairColor().option); + // face + buffer.writeInt(character.getAppearance().getFace().option); + // max hp + buffer.writeDouble(character.getStats().getMaxHP()); + // max mp + buffer.writeDouble(character.getStats().getMaxMP()); + + // time left before character is deleted (in seconds?) TODO + buffer.writeInt(0x00); + + buffer.writeInt(character.getCharacterClass().id); + + // 0x01 auto selects this character. TODO + buffer.writeInt(0x00); + // enchant effect TODO + buffer.writeByte(0x16); + // augmentation id + buffer.writeInt(0x00); + + + } + } + + /** + * Writes the paperdoll item id + * + * @param buffer + * the buffer + * @param character + * the character + * @param paperdoll + * the slot + */ + private void writePaperdollItemID(ChannelBuffer buffer, + L2Character character, InventoryPaperdoll paperdoll) { + final Item item = character.getInventory().getItem(paperdoll); + int id = 0; + if (item != null) + id = item.getTemplateID().getID(); + buffer.writeInt(id); + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_MOVE_TYPE.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_MOVE_TYPE.java new file mode 100644 index 000000000..16aeedb45 --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_MOVE_TYPE.java @@ -0,0 +1,56 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.packet.server; + +import org.jboss.netty.buffer.ChannelBuffer; + +import com.l2jserver.model.world.L2Character; +import com.l2jserver.service.network.model.Lineage2Client; +import com.l2jserver.service.network.model.packet.AbstractServerPacket; + +/** + * This packet updates the movement type + * + * @author Rogiel + */ +public class SM_CHAR_MOVE_TYPE extends AbstractServerPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0x2e;//0x28; + + /** + * The character + */ + private final L2Character character; + + /** + * @param character + * the character + */ + public SM_CHAR_MOVE_TYPE(L2Character character) { + super(OPCODE); + this.character = character; + } + + @Override + public void write(Lineage2Client conn, ChannelBuffer buffer) { + buffer.writeInt(character.getID().getID()); + buffer.writeInt(character.getMoveType().id); + buffer.writeInt(0x00); // unk + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_OPEN_MAP.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_OPEN_MAP.java new file mode 100644 index 000000000..077760f4e --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_OPEN_MAP.java @@ -0,0 +1,54 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.packet.server; + +import org.jboss.netty.buffer.ChannelBuffer; + +import com.l2jserver.service.network.model.Lineage2Client; +import com.l2jserver.service.network.model.packet.AbstractServerPacket; + +/** + * An packet authorizing the client to open the map + * + * @author Rogiel + */ +public class SM_CHAR_OPEN_MAP extends AbstractServerPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0x9d; + + /** + * The map ID + */ + private final int mapID; + + /** + * @param mapID + * the map id + */ + public SM_CHAR_OPEN_MAP(int mapID) { + super(OPCODE); + this.mapID = mapID; + } + + @Override + public void write(Lineage2Client conn, ChannelBuffer buffer) { + buffer.writeInt(mapID); + buffer.writeByte(0x00); // seven signs period + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_RESTART.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_RESTART.java new file mode 100644 index 000000000..d39cfde1d --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_RESTART.java @@ -0,0 +1,68 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.packet.server; + +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 + * + * @author Rogiel + */ +public class SM_CHAR_RESTART extends AbstractServerPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0x5f; + + /** + * The restart state + */ + private boolean state; + + /** + * @param state + * the state + */ + public SM_CHAR_RESTART(boolean state) { + super(OPCODE); + this.state = state; + } + + /** + * @return an OK instance of this packet + */ + public static SM_CHAR_RESTART ok() { + return new SM_CHAR_RESTART(true); + } + + /** + * @return an FAILED instance of this packet + */ + public static SM_CHAR_RESTART denied() { + return new SM_CHAR_RESTART(false); + } + + @Override + public void write(Lineage2Client conn, ChannelBuffer buffer) { + buffer.writeByte((state ? 0x01 : 0x00)); + //TODO 5F=RestartResponse:d(ok)s(Message) + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_SELECTED.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_SELECTED.java new file mode 100644 index 000000000..01152e524 --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_SELECTED.java @@ -0,0 +1,109 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.packet.server; + +import org.jboss.netty.buffer.ChannelBuffer; + +import com.l2jserver.model.world.L2Character; +import com.l2jserver.model.world.actor.ActorExperience; +import com.l2jserver.service.network.model.Lineage2Client; +import com.l2jserver.service.network.model.packet.AbstractServerPacket; +import com.l2jserver.util.BufferUtils; + +/** + * This packet notifies the client that the chosen character has been + * successfully selected. + * + * @author Rogiel + */ +public class SM_CHAR_SELECTED extends AbstractServerPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0x15; + + /** + * The selected character + */ + private final L2Character character; + + /** + * @param character + * the character + */ + public SM_CHAR_SELECTED(L2Character character) { + super(OPCODE); + this.character = character; + } + + @Override + public void write(Lineage2Client conn, ChannelBuffer buffer) { + BufferUtils.writeString(buffer, character.getName()); + buffer.writeInt(character.getID().getID()); + BufferUtils.writeString(buffer, "It works!"); // title + buffer.writeInt(conn.getSession().getPlayKey1()); + buffer.writeInt((character.getClanID() != null ? character.getClanID() + .getID() : 0)); + buffer.writeInt(0x00); // ?? + buffer.writeInt(character.getSex().option); + buffer.writeInt(character.getRace().id); + buffer.writeInt(character.getCharacterClass().id); + buffer.writeInt(0x01); // active ?? + buffer.writeInt(character.getPoint().getX()); + buffer.writeInt(character.getPoint().getY()); + buffer.writeInt(character.getPoint().getZ()); + + buffer.writeDouble(20); // cur hp + buffer.writeDouble(20); // cur mp + buffer.writeInt(0); // sp + buffer.writeLong(ActorExperience.LEVEL_1.experience); + buffer.writeInt(ActorExperience.LEVEL_1.level); + buffer.writeInt(0); // karma + buffer.writeInt(0); // pk + buffer.writeInt(character.getStats().getIntelligence()); + buffer.writeInt(character.getStats().getStrength()); + buffer.writeInt(character.getStats().getConcentration()); + buffer.writeInt(character.getStats().getMentality()); + buffer.writeInt(character.getStats().getDexterity()); + buffer.writeInt(character.getStats().getWitness()); + + for(int i = 0; i < 30; i++) + { + buffer.writeInt(0x00); + } + + buffer.writeInt(0); // unk + buffer.writeInt(0x00); // unk + + buffer.writeInt(0); // game time + + buffer.writeInt(0x00); + buffer.writeInt(0x00); + buffer.writeInt(0x00); + buffer.writeInt(0x00); + buffer.writeInt(0x00); + buffer.writeInt(0x00); + buffer.writeInt(0x00); + buffer.writeInt(0x00); + buffer.writeInt(0x00); + buffer.writeInt(0x00); + buffer.writeInt(0x00); + buffer.writeInt(0x00); + buffer.writeInt(0x00); + buffer.writeInt(0x00); + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_SHORTCUT_LIST.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_SHORTCUT_LIST.java new file mode 100644 index 000000000..e9e9d6e59 --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_SHORTCUT_LIST.java @@ -0,0 +1,71 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.packet.server; + +import org.jboss.netty.buffer.ChannelBuffer; + +import com.l2jserver.model.game.CharacterShortcut; +import com.l2jserver.model.world.character.CharacterShortcutContainer; +import com.l2jserver.service.network.model.Lineage2Client; +import com.l2jserver.service.network.model.packet.AbstractServerPacket; + +/** + * This packet sends to the client his shortcut list + * + * @author Rogiel + */ +public class SM_CHAR_SHORTCUT_LIST extends AbstractServerPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0x45; + + /** + * The shortcut list + */ + private final CharacterShortcutContainer shortcuts; + + /** + * @param shortcuts + * the shortcuts container + */ + public SM_CHAR_SHORTCUT_LIST(CharacterShortcutContainer shortcuts) { + super(OPCODE); + this.shortcuts = shortcuts; + } + + @Override + public void write(Lineage2Client conn, ChannelBuffer buffer) { + buffer.writeInt(shortcuts.getShortcutCount()); + for (final CharacterShortcut shortcut : shortcuts) { + buffer.writeInt(shortcut.getType().id); + buffer.writeInt(shortcut.getPage() * 12 + shortcut.getSlot()); + switch (shortcut.getType()) { + case ITEM: + buffer.writeInt(shortcut.getItemID().getID()); + buffer.writeInt(0x01); // unk1f + buffer.writeInt(-1); // reuse group + buffer.writeInt(0x00); // unk2 + buffer.writeInt(0x00); // unk3 + buffer.writeShort(0x00); // unk4 + buffer.writeShort(0x00); // unk5 + break; + // TODO: SKILL, ACTION, MACRO, RECIPE + } + } + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_SHORTCUT_REGISTER.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_SHORTCUT_REGISTER.java new file mode 100644 index 000000000..055cb3037 --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_SHORTCUT_REGISTER.java @@ -0,0 +1,69 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.packet.server; + +import org.jboss.netty.buffer.ChannelBuffer; + +import com.l2jserver.model.game.CharacterShortcut; +import com.l2jserver.service.network.model.Lineage2Client; +import com.l2jserver.service.network.model.packet.AbstractServerPacket; + +/** + * This packet informs the client that a new shortcut has been created + * + * @author Rogiel + */ +public class SM_CHAR_SHORTCUT_REGISTER extends AbstractServerPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0x44; + + /** + * The shortcut + */ + private final CharacterShortcut shortcut; + + /** + * @param shortcut + * the shortcut registered + */ + public SM_CHAR_SHORTCUT_REGISTER(CharacterShortcut shortcut) { + super(OPCODE); + this.shortcut = shortcut; + } + + @Override + public void write(Lineage2Client conn, ChannelBuffer buffer) { + buffer.writeInt(shortcut.getType().id); + buffer.writeInt(shortcut.getPage() * 12 + shortcut.getSlot()); + switch (shortcut.getType()) { + case ITEM: + buffer.writeInt(shortcut.getItemID().getID()); + // buffer.writeInt(0x01); // unk1f + // buffer.writeInt(-1); // reuse group + // buffer.writeInt(0x00); // unk2 + // buffer.writeInt(0x00); // unk3 + // buffer.writeShort(0x00); // unk4 + // buffer.writeShort(0x00); // unk5 + break; + default: + buffer.writeInt(shortcut.getID().getID()); + } + buffer.writeInt(1); // unknown + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_STOP.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_STOP.java new file mode 100644 index 000000000..c122d8bf4 --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_STOP.java @@ -0,0 +1,58 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.packet.server; + +import org.jboss.netty.buffer.ChannelBuffer; + +import com.l2jserver.model.world.L2Character; +import com.l2jserver.service.network.model.Lineage2Client; +import com.l2jserver.service.network.model.packet.AbstractServerPacket; + +/** + * An packet that sends all character templates to the client. + * + * @author Rogiel + */ +public class SM_CHAR_STOP extends AbstractServerPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0x47; + + /** + * The character + */ + private L2Character character; + + /** + * @param character + * the character + */ + public SM_CHAR_STOP(L2Character character) { + super(OPCODE); + this.character = character; + } + + @Override + public void write(Lineage2Client conn, ChannelBuffer buffer) { + buffer.writeInt(character.getID().getID()); + buffer.writeInt(character.getPoint().getX()); + buffer.writeInt(character.getPoint().getY()); + buffer.writeInt(character.getPoint().getZ()); + buffer.writeInt((int) character.getPoint().getAngle()); + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_TARGET.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_TARGET.java new file mode 100644 index 000000000..8040bad7b --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_TARGET.java @@ -0,0 +1,71 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.packet.server; + +import org.jboss.netty.buffer.ChannelBuffer; + +import com.l2jserver.model.world.Actor; +import com.l2jserver.service.network.model.Lineage2Client; +import com.l2jserver.service.network.model.packet.AbstractServerPacket; + +/** + * This packet notifies the client that the chosen character has been + * successfully selected. + * + * @author Rogiel + */ +public class SM_CHAR_TARGET extends AbstractServerPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0xa6; + + /** + * The selected character + */ + private final Actor object; + /** + * The name color + */ + private int color; + + /** + * @param object + * the target + * @param color + * the name color + */ + public SM_CHAR_TARGET(Actor object, int color) { + super(OPCODE); + this.object = object; + this.color = color; + } + + /** + * @param object + * the target + */ + public SM_CHAR_TARGET(Actor object) { + this(object, 0); + } + + @Override + public void write(Lineage2Client conn, ChannelBuffer buffer) { + buffer.writeInt(object.getID().getID()); + buffer.writeShort(color); + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_TARGET_UNSELECT.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_TARGET_UNSELECT.java new file mode 100644 index 000000000..9e68e8313 --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_TARGET_UNSELECT.java @@ -0,0 +1,59 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.packet.server; + +import org.jboss.netty.buffer.ChannelBuffer; + +import com.l2jserver.model.world.L2Character; +import com.l2jserver.service.network.model.Lineage2Client; +import com.l2jserver.service.network.model.packet.AbstractServerPacket; + +/** + * This packet notifies the client that the chosen character has been + * successfully selected. + * + * @author Rogiel + */ +public class SM_CHAR_TARGET_UNSELECT extends AbstractServerPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0x2a; + + /** + * The character that as unselected an object + */ + private final L2Character character; + + /** + * @param character + * the character + */ + public SM_CHAR_TARGET_UNSELECT(L2Character character) { + super(OPCODE); + this.character = character; + } + + @Override + public void write(Lineage2Client conn, ChannelBuffer buffer) { + buffer.writeInt(character.getID().getID()); + buffer.writeInt(character.getPoint().getX()); + buffer.writeInt(character.getPoint().getY()); + buffer.writeInt(character.getPoint().getZ()); + buffer.writeInt(0x00); // ?? + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_TELEPORT.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_TELEPORT.java new file mode 100644 index 000000000..088e1c997 --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_TELEPORT.java @@ -0,0 +1,68 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.packet.server; + +import org.jboss.netty.buffer.ChannelBuffer; + +import com.l2jserver.model.world.L2Character; +import com.l2jserver.service.network.model.Lineage2Client; +import com.l2jserver.service.network.model.packet.AbstractServerPacket; +import com.l2jserver.util.geometry.Point3D; + +/** + * This packet notifies the client that the chosen character has been + * successfully selected. + * + * @author Rogiel + */ +public class SM_CHAR_TELEPORT extends AbstractServerPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0x28; + + /** + * The selected character + */ + private final L2Character character; + /** + * The teleportation point + */ + private final Point3D point; + + /** + * @param character + * the character + * @param point + * the teleport point + */ + public SM_CHAR_TELEPORT(L2Character character, Point3D point) { + super(OPCODE); + this.character = character; + this.point = point; + } + + @Override + public void write(Lineage2Client conn, ChannelBuffer buffer) { + buffer.writeInt(character.getID().getID()); + buffer.writeInt(point.getX()); + buffer.writeInt(point.getY()); + buffer.writeInt(point.getZ()); + buffer.writeInt(0x00); // isValidation ?? + buffer.writeInt((int) point.getAngle()); // nYaw + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_TEMPLATE.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_TEMPLATE.java new file mode 100644 index 000000000..8b54810b2 --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_TEMPLATE.java @@ -0,0 +1,76 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.packet.server; + +import org.jboss.netty.buffer.ChannelBuffer; + +import com.l2jserver.model.template.CharacterTemplate; +import com.l2jserver.service.network.model.Lineage2Client; +import com.l2jserver.service.network.model.packet.AbstractServerPacket; + +/** + * An packet that sends all character templates to the client. + * + * @author Rogiel + */ +public class SM_CHAR_TEMPLATE extends AbstractServerPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0x17; + + /** + * The character template list + */ + private CharacterTemplate[] templates; + + /** + * @param templates + * the character templates + */ + public SM_CHAR_TEMPLATE(CharacterTemplate... templates) { + super(OPCODE); + this.templates = templates; + } + + @Override + public void write(Lineage2Client conn, ChannelBuffer buffer) { + buffer.writeInt(templates.length); + for (final CharacterTemplate template : templates) { + buffer.writeInt(template.getID().getCharacterClass().race.id); + buffer.writeInt(template.getID().getCharacterClass().id); + buffer.writeInt(0x46); + buffer.writeInt(template.getStats().getBase().getStr()); + buffer.writeInt(0x0a); + buffer.writeInt(0x46); + buffer.writeInt(template.getStats().getBase().getDex()); + buffer.writeInt(0x0a); + buffer.writeInt(0x46); + buffer.writeInt(template.getStats().getBase().getDex()); + buffer.writeInt(0x0a); + buffer.writeInt(0x46); + buffer.writeInt(template.getStats().getBase().getInt()); + buffer.writeInt(0x0a); + buffer.writeInt(0x46); + buffer.writeInt(template.getStats().getBase().getWit()); + buffer.writeInt(0x0a); + buffer.writeInt(0x46); + buffer.writeInt(template.getStats().getBase().getMen()); + buffer.writeInt(0x0a); + } + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_COMMUNITY_HTML.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_COMMUNITY_HTML.java new file mode 100644 index 000000000..7e8f81cd2 --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_COMMUNITY_HTML.java @@ -0,0 +1,76 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.packet.server; + +import org.htmlparser.tags.Html; +import org.jboss.netty.buffer.ChannelBuffer; + +import com.l2jserver.service.network.model.Lineage2Client; +import com.l2jserver.service.network.model.packet.AbstractServerPacket; +import com.l2jserver.util.BufferUtils; +import com.l2jserver.util.html.markup.HtmlTemplate; + +/** + * This packet sends an HTML message to be displayed in the client. As opposed + * to {@link SM_HTML}, this one displays it in the community board window. + * + * @author Rogiel + */ +public class SM_COMMUNITY_HTML extends AbstractServerPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0x7b; + + /** + * The HTML contents + */ + private final String html; + + /** + * @param html + * the html + */ + public SM_COMMUNITY_HTML(String html) { + super(OPCODE); + this.html = html; + } + + /** + * @param html + * the html + */ + public SM_COMMUNITY_HTML(Html html) { + super(OPCODE); + this.html = html.toHtml(); + } + + /** + * @param template + * the html template + */ + public SM_COMMUNITY_HTML(HtmlTemplate template) { + super(OPCODE); + this.html = template.toHtmlString(); + } + + @Override + public void write(Lineage2Client conn, ChannelBuffer buffer) { + buffer.writeByte(0x01); // display or hide + BufferUtils.writeString(buffer, html); + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_FORT_INFO.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_FORT_INFO.java new file mode 100644 index 000000000..90515570f --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_FORT_INFO.java @@ -0,0 +1,57 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.packet.server; + +import org.jboss.netty.buffer.ChannelBuffer; + +import com.l2jserver.service.network.model.Lineage2Client; +import com.l2jserver.service.network.model.packet.AbstractServerPacket; +import com.l2jserver.util.BufferUtils; + +/** + * This packet send the manor list to the client + * + * @author Rogiel + */ +public class SM_FORT_INFO extends AbstractServerPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0xfe; + + /** + * Creates a new instance + */ + public SM_FORT_INFO() { + super(OPCODE); + } + + @Override + public void write(Lineage2Client conn, ChannelBuffer buffer) { + buffer.writeShort(0x15); + buffer.writeInt(21); + int i = 101; + for (; i < 122; i++) { + buffer.writeInt(i); // fort id + BufferUtils.writeString(buffer, ""); // clan name + buffer.writeInt(0x00); // is in siege + buffer.writeInt(0x00); // Time of possession + } + + // TODO implement fort service + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_GG_QUERY.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_GG_QUERY.java new file mode 100644 index 000000000..213fd14ea --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_GG_QUERY.java @@ -0,0 +1,77 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.packet.server; + +import org.jboss.netty.buffer.ChannelBuffer; + +import com.google.common.base.Preconditions; +import com.l2jserver.service.network.model.Lineage2Client; +import com.l2jserver.service.network.model.packet.AbstractServerPacket; + +/** + * This packet send the GameGuard query to the client. The client will send an + * notification, but this can be ignored if GG is not supposed to be enforced. + * + * @author Rogiel + */ +public class SM_GG_QUERY extends AbstractServerPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0xf9; + /** + * The GG key + */ + private final int[] key; + + /** + * @param key + * the game guard key + */ + public SM_GG_QUERY(int[] key) { + super(OPCODE); + Preconditions.checkArgument(key.length == 4, + "key must by an 4-length array"); + this.key = key; + } + + /** + * @param key1 + * the game guard key 1 + * @param key2 + * the game guard key 2 + * @param key3 + * the game guard key 3 + * @param key4 + * the game guard key 4 + */ + public SM_GG_QUERY(int key1, int key2, int key3, int key4) { + super(OPCODE); + this.key = new int[4]; + this.key[0] = key1; + this.key[1] = key2; + this.key[2] = key3; + this.key[3] = key4; + } + + @Override + public void write(Lineage2Client conn, ChannelBuffer buffer) { + for (final int part : key) { + buffer.writeInt(part); + } + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_HTML.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_HTML.java new file mode 100644 index 000000000..a94c86cbc --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_HTML.java @@ -0,0 +1,114 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.packet.server; + +import org.htmlparser.tags.Html; +import org.jboss.netty.buffer.ChannelBuffer; + +import com.l2jserver.model.world.NPC; +import com.l2jserver.service.network.model.Lineage2Client; +import com.l2jserver.service.network.model.packet.AbstractServerPacket; +import com.l2jserver.util.BufferUtils; +import com.l2jserver.util.html.markup.HtmlTemplate; + +/** + * This packet sends an HTML message to be displayed in the client. + * + * @author Rogiel + */ +public class SM_HTML extends AbstractServerPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0x0f; + + /** + * The saying NPC + */ + private final NPC npc; + /** + * The HTML contents + */ + private final String html; + + /** + * @param npc + * the npc instance + * @param html + * the html + */ + public SM_HTML(NPC npc, String html) { + super(OPCODE); + this.npc = npc; + this.html = html; + } + + /** + * @param npc + * the npc instance + * @param html + * the html + */ + public SM_HTML(NPC npc, Html html) { + super(OPCODE); + this.npc = npc; + this.html = html.toHtml(); + } + + /** + * @param npc + * the npc instance + * @param template + * the html template + */ + public SM_HTML(NPC npc, HtmlTemplate template) { + super(OPCODE); + this.npc = npc; + this.html = template.toHtmlString(); + } + + /** + * @param html + * the html + */ + public SM_HTML(String html) { + this(null, html); + } + + /** + * @param html + * the html + */ + public SM_HTML(Html html) { + this(null, html); + } + + /** + * @param template + * the html template + */ + public SM_HTML(HtmlTemplate template) { + this(null, template); + } + + @Override + public void write(Lineage2Client conn, ChannelBuffer buffer) { + buffer.writeInt((npc != null ? npc.getID().getID() : 0x01)); + BufferUtils.writeString(buffer, html); + buffer.writeInt(0x00); // item id + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_ITEM_GROUND.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_ITEM_GROUND.java new file mode 100644 index 000000000..ef582527e --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_ITEM_GROUND.java @@ -0,0 +1,65 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.packet.server; + +import org.jboss.netty.buffer.ChannelBuffer; + +import com.l2jserver.model.world.Item; +import com.l2jserver.service.network.model.Lineage2Client; +import com.l2jserver.service.network.model.packet.AbstractServerPacket; + +/** + * This packet sends an item that is dropped on the ground + * + * @author Rogiel + */ +public class SM_ITEM_GROUND extends AbstractServerPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0x16; + /** + * The item that is on the ground + */ + private final Item item; + + /** + * @param item + * the item that is on the ground + */ + public SM_ITEM_GROUND(Item item) { + super(OPCODE); + this.item = item; + } + + @Override + public void write(Lineage2Client conn, ChannelBuffer buffer) { + buffer.writeInt((item.getOwnerID() != null ? item.getOwnerID().getID() + : 0)); // char who dropped + buffer.writeInt(item.getID().getID()); // item obj id + buffer.writeInt(item.getTemplateID().getID()); // item template id + + buffer.writeInt(item.getPoint().getX()); // x + buffer.writeInt(item.getPoint().getY()); // y + buffer.writeInt(item.getPoint().getZ()); // z + // only show item count if it is a stackable item + buffer.writeInt(0x01); // show count + buffer.writeLong(item.getCount()); // count + + buffer.writeInt(0); // unknown + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_ITEM_PICK.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_ITEM_PICK.java new file mode 100644 index 000000000..f76ce18e2 --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_ITEM_PICK.java @@ -0,0 +1,69 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.packet.server; + +import org.jboss.netty.buffer.ChannelBuffer; + +import com.l2jserver.model.server.AttackHit; +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.packet.AbstractServerPacket; + +/** + * This packet makes an character pick up an item + * + * @author Rogiel + * @see AttackHit + */ +public class SM_ITEM_PICK extends AbstractServerPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0x17; + + /** + * The {@link Item} being picked up + */ + private final Item item; + /** + * The {@link L2Character} picking the item + */ + private final L2Character character; + + /** + * @param character + * the character that is picking the item + * @param item + * the item that is being picked + */ + public SM_ITEM_PICK(L2Character character, Item item) { + super(OPCODE); + this.item = item; + this.character = character; + } + + @Override + public void write(Lineage2Client conn, ChannelBuffer buffer) { + buffer.writeInt(character.getID().getID()); + buffer.writeInt(item.getID().getID()); + + buffer.writeInt(item.getPoint().getX()); + buffer.writeInt(item.getPoint().getY()); + buffer.writeInt(item.getPoint().getZ()); + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_KEY.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_KEY.java new file mode 100644 index 000000000..884e1c864 --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_KEY.java @@ -0,0 +1,134 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.packet.server; + +import java.util.Arrays; + +import org.jboss.netty.buffer.ChannelBuffer; + +import com.l2jserver.service.network.model.Lineage2Client; +import com.l2jserver.service.network.model.Lineage2CryptographyKey; +import com.l2jserver.service.network.model.packet.AbstractServerPacket; + +/** + * This packet send the encryptation keys for the client. After this message all + * communication is done with the cryptography engine enabled. + * + *
+ * (c) cbddcd
+ * 
+ * + * @author Rogiel + */ +public class SM_KEY extends AbstractServerPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0x00; + + /** + * 8-byte key cryptography key + */ + private byte[] key; + /** + * The protocol state. True if valid, false if not. + */ + private boolean status; + + /** + * @param key + * the cryptography key + * @param status + * the status + */ + public SM_KEY(Lineage2CryptographyKey key, boolean status) { + super(OPCODE); + this.key = Arrays.copyOfRange(key.key, 0, 8); + this.status = status; + } + + /** + * Creates a new {@link SM_KEY} with key and valid protocol. + * + * @param key + * the key + * @return the new instance + */ + public static SM_KEY valid(Lineage2CryptographyKey key) { + return new SM_KEY(key, true); + } + + /** + * Creates a new {@link SM_KEY} with key and invalid protocol. + * + * @param key + * the key + * @return the new instance + */ + public static SM_KEY invalid(Lineage2CryptographyKey key) { + return new SM_KEY(key, false); + } + + @Override + public void write(Lineage2Client conn, ChannelBuffer buffer) { +// buffer.writeByte((status ? 0x01 : 0x00)); +// for (int i = 0; i < 8; i++) { +// buffer.writeByte(key[i]); +// } +// // buffer.writeBytes(key); +// buffer.writeInt(0x01); +// buffer.writeInt(0x01); // server id +// buffer.writeByte(0x01); +// buffer.writeInt(0x00); // obfuscation key + // + buffer.writeByte((status ? 0x01 : 0x00)); + buffer.writeBytes(key, 0, 8); + buffer.writeInt(0x01); + buffer.writeInt(0x01); + + } + + /** + * @return the key + */ + public byte[] getKey() { + return key; + } + + /** + * @param key + * the key to set + */ + public void setKey(byte[] key) { + this.key = key; + } + + /** + * @return the status + */ + public boolean isStatus() { + return status; + } + + /** + * @param status + * the status to set + */ + public void setStatus(boolean status) { + this.status = status; + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_MANOR_LIST.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_MANOR_LIST.java new file mode 100644 index 000000000..377f32692 --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_MANOR_LIST.java @@ -0,0 +1,64 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.packet.server; + +import org.jboss.netty.buffer.ChannelBuffer; + +import com.l2jserver.service.network.model.Lineage2Client; +import com.l2jserver.service.network.model.packet.AbstractServerPacket; +import com.l2jserver.util.BufferUtils; + +/** + * This packet send the manor list to the client + * + * @author Rogiel + */ +public class SM_MANOR_LIST extends AbstractServerPacket { + /** + * The packet OPCODE1 + */ + public static final int OPCODE1 = 0xfe; + /** + * The packet OPCODE2 + */ + public static final int OPCODE2 = 0x1b; + + /** + * List of manors to be sent + */ + private String[] manors; + + /** + * @param manors + * the manors + */ + public SM_MANOR_LIST(String... manors) { + super(OPCODE1); + this.manors = manors; + } + + @Override + public void write(Lineage2Client conn, ChannelBuffer buffer) { + buffer.writeShort(OPCODE2); + buffer.writeInt(manors.length); + int i = 1; + for (String manor : manors) { + buffer.writeInt(i++); + BufferUtils.writeString(buffer, manor); + } + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_NPC_INFO.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_NPC_INFO.java new file mode 100644 index 000000000..f0d39f3d5 --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_NPC_INFO.java @@ -0,0 +1,124 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.packet.server; + +import org.jboss.netty.buffer.ChannelBuffer; + +import com.l2jserver.model.template.NPCTemplate; +import com.l2jserver.model.world.NPC; +import com.l2jserver.service.network.model.Lineage2Client; +import com.l2jserver.service.network.model.packet.AbstractServerPacket; +import com.l2jserver.util.BufferUtils; + +/** + * This packet sends to the client an actor information about an actor + * + * @author Rogiel + */ +public class SM_NPC_INFO extends AbstractServerPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0x16; + /** + * The {@link NPC} + */ + private final NPC npc; + + /** + * @param npc + * the npc + */ + public SM_NPC_INFO(NPC npc) { + super(OPCODE); + this.npc = npc; + } + + @Override + public void write(Lineage2Client conn, ChannelBuffer buffer) { + final NPCTemplate template = npc.getTemplate(); + + buffer.writeInt(npc.getID().getID()); + buffer.writeInt(template.getID().getID() + 1000000); // npctype + // id + // buffer.writeInt((template.isAttackable() ? 0x01 : 0x00)); // + // attackable + // FIXME unhard code it + buffer.writeInt(0x00); // attackable + buffer.writeInt(npc.getPoint().getX()); + buffer.writeInt(npc.getPoint().getY()); + buffer.writeInt(npc.getPoint().getZ()); + buffer.writeInt((int) npc.getPoint().getAngle()); + buffer.writeInt(0x00); // unk + buffer.writeInt(npc.getStats().getMagicalAttackSpeed()); + buffer.writeInt(npc.getStats().getPhysicalAttackSpeed()); + buffer.writeInt(npc.getStats().getRunSpeed()); + buffer.writeInt(npc.getStats().getWalkSpeed()); + buffer.writeInt(npc.getStats().getRunSpeed()); // swim run speed + buffer.writeInt(npc.getStats().getWalkSpeed()); // swim walk speed + buffer.writeInt(npc.getStats().getRunSpeed()); // swim run speed + buffer.writeInt(npc.getStats().getWalkSpeed()); // swim walk speed + buffer.writeInt(npc.getStats().getRunSpeed()); // fly run speed + buffer.writeInt(npc.getStats().getWalkSpeed()); // fly run speed + buffer.writeDouble(0x01); // TODO multiplier? + buffer.writeDouble(0x01);// TODO multiplier? + buffer.writeDouble(template.getInfo().getCollision().getRadius()); + buffer.writeDouble(template.getInfo().getCollision().getHeigth()); + if (template.getInfo().getItem() != null) { + buffer.writeInt((template.getInfo().getItem().getRightHand() != null ? template + .getInfo().getItem().getRightHand().getID() + : 0x00)); + } else { + buffer.writeInt(0x00); + } + buffer.writeInt(0x00); // chest + if (template.getInfo().getItem() != null) { + buffer.writeInt((template.getInfo().getItem().getLeftHand() != null ? template + .getInfo().getItem().getLeftHand().getID() + : 0x00)); + } else { + buffer.writeInt(0x00); + } + buffer.writeByte(1); // name above char 1=true ... ?? + buffer.writeByte(0x01); // is running + buffer.writeByte((npc.isAttacking() ? 0x01 : 0x00)); // is in combat + buffer.writeByte((npc.isDead() ? 0x01 : 0x00)); // is like dead (faking) + buffer.writeByte(0x00); // 0=teleported 1=default 2=summoned + BufferUtils.writeString(buffer, + (template.getInfo().getName() != null ? template.getInfo() + .getName().getValue() : null)); + BufferUtils.writeString(buffer, + (template.getInfo().getTitle() != null ? template.getInfo() + .getTitle().getValue() : null)); + buffer.writeInt(0x00); // Title color 0=client default, 1 for summons + buffer.writeInt(0x00); // pvp flag TODO + buffer.writeInt(0x00); // karma TODO + + buffer.writeInt(0x00); // C2 - abnormal effect TODO + buffer.writeInt(0x00); // clan id + buffer.writeInt(0x00); // crest id + buffer.writeInt(0x00); // ally id + buffer.writeInt(0x00); // all crest + buffer.writeByte(0x00); // C2 - is flying + + buffer.writeByte(0x00); // title color 0=client OR circle 1-blue, 2-red? + buffer.writeDouble(template.getInfo().getCollision().getRadius()); + buffer.writeDouble(template.getInfo().getCollision().getHeigth()); + buffer.writeInt(0x00); // C4 - enchant effect + buffer.writeInt(0x00); // C6 -- is flying + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_OBJECT_REMOVE.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_OBJECT_REMOVE.java new file mode 100644 index 000000000..3f6f0ef9e --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_OBJECT_REMOVE.java @@ -0,0 +1,56 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.packet.server; + +import org.jboss.netty.buffer.ChannelBuffer; + +import com.l2jserver.model.world.PositionableObject; +import com.l2jserver.service.network.model.Lineage2Client; +import com.l2jserver.service.network.model.packet.AbstractServerPacket; + +/** + * This packet informs the client that an certain object has disappeared from + * his sight or from the world. + * + * @author Rogiel + */ +public class SM_OBJECT_REMOVE extends AbstractServerPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0x08; + + /** + * The Object + */ + private final PositionableObject object; + + /** + * @param object + * the object to be removed + */ + public SM_OBJECT_REMOVE(PositionableObject object) { + super(OPCODE); + this.object = object; + } + + @Override + public void write(Lineage2Client conn, ChannelBuffer buffer) { + buffer.writeInt(object.getID().getID()); + buffer.writeInt(0x00); + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_SERVER_OBJECT.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_SERVER_OBJECT.java new file mode 100644 index 000000000..3196fc5aa --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_SERVER_OBJECT.java @@ -0,0 +1,76 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.packet.server; + +import org.jboss.netty.buffer.ChannelBuffer; + +import com.l2jserver.model.template.NPCTemplate; +import com.l2jserver.model.world.NPC; +import com.l2jserver.service.network.model.Lineage2Client; +import com.l2jserver.service.network.model.packet.AbstractServerPacket; +import com.l2jserver.util.BufferUtils; + +/** + * This packet sends to the client an actor information about an actor (except + * players) + * + * @author Rogiel + */ +public class SM_SERVER_OBJECT extends AbstractServerPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0x92; + /** + * The {@link NPC} + */ + private final NPC npc; + + /** + * @param npc + * the npc + */ + public SM_SERVER_OBJECT(NPC npc) { + super(OPCODE); + this.npc = npc; + } + + @Override + public void write(Lineage2Client conn, ChannelBuffer buffer) { + final NPCTemplate template = npc.getTemplate(); + + buffer.writeInt(npc.getID().getID()); // obj id + buffer.writeInt(npc.getTemplateID().getID() + 1000000); // template id + BufferUtils + .writeString(buffer, template.getInfo().getName().getValue()); // name + buffer.writeInt((template.getInfo().isAttackable() ? 0x01 : 0x00)); // attackable + buffer.writeInt(npc.getPoint().getX()); // x + buffer.writeInt(npc.getPoint().getY()); // y + buffer.writeInt(npc.getPoint().getZ()); // z + buffer.writeInt((int) npc.getPoint().getAngle()); // angle + buffer.writeDouble(0x01); // move mult + buffer.writeDouble(0x01); // attack spd mult + buffer.writeDouble(template.getInfo().getCollision().getRadius()); + buffer.writeDouble(template.getInfo().getCollision().getHeigth()); + buffer.writeInt((int) (template.getInfo().isAttackable() ? npc.getHP() + : 0x00)); + buffer.writeInt((int) (template.getInfo().isAttackable() ? template + .getInfo().getStats().getHp() : 0x00)); + buffer.writeInt(0x01); // object type + buffer.writeInt(0x00); // special effects + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_SYSTEM_MESSAGE.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_SYSTEM_MESSAGE.java new file mode 100644 index 000000000..3091fc479 --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/game/net/packet/server/SM_SYSTEM_MESSAGE.java @@ -0,0 +1,377 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.game.net.packet.server; + +import java.util.List; + +import org.jboss.netty.buffer.ChannelBuffer; + +import com.l2jserver.model.game.Castle; +import com.l2jserver.model.game.Fort; +import com.l2jserver.model.game.Skill; +import com.l2jserver.model.template.ItemTemplate; +import com.l2jserver.model.template.SkillTemplate; +import com.l2jserver.model.world.Actor; +import com.l2jserver.model.world.Item; +import com.l2jserver.model.world.NPC; +import com.l2jserver.service.network.model.Lineage2Client; +import com.l2jserver.service.network.model.SystemMessage; +import com.l2jserver.service.network.model.packet.AbstractServerPacket; +import com.l2jserver.util.BufferUtils; +import com.l2jserver.util.factory.CollectionFactory; + +/** + * This packet sends an System Message to the client. Most messages appear in + * the console. + * + * @author Rogiel + */ +public class SM_SYSTEM_MESSAGE extends AbstractServerPacket { + /** + * The packet OPCODE + */ + public static final int OPCODE = 0x64; + + /** + * The System message id + */ + private int id; + /** + * The system message parameters + */ + private List params = CollectionFactory + .newList(); + + /** + * System message parameter IDs + * + * @author Rogiel + */ + public interface SystemMessagePacketParameter { + /** + * String parameter + */ + public static final byte TYPE_SYSTEM_STRING = 13; + /** + * Player name parameter + */ + public static final byte TYPE_PLAYER_NAME = 12; + // id 11 - unknown + /** + * Instance name parameter + */ + public static final byte TYPE_INSTANCE_NAME = 10; + /** + * Element name parameter + */ + public static final byte TYPE_ELEMENT_NAME = 9; + // id 8 - same as 3 + /** + * Zone name parameter + */ + public static final byte TYPE_ZONE_NAME = 7; + /** + * {@link Item} number parameter + */ + public static final byte TYPE_ITEM_NUMBER = 6; + /** + * {@link Castle} name parameter + */ + public static final byte TYPE_CASTLE_NAME = 5; + /** + * {@link Skill} name parameter + */ + public static final byte TYPE_SKILL_NAME = 4; + /** + * {@link Item} name parameter + */ + public static final byte TYPE_ITEM_NAME = 3; + /** + * {@link NPC} name parameter + */ + public static final byte TYPE_NPC_NAME = 2; + /** + * Number parameter + */ + public static final byte TYPE_NUMBER = 1; + /** + * Text parameter + */ + public static final byte TYPE_TEXT = 0; + + /** + * @param conn + * the connection + * @param buffer + * the buffer + */ + void write(Lineage2Client conn, ChannelBuffer buffer); + } + + /** + * Creates a new instance + * + * @param message + * the {@link SystemMessage} + */ + public SM_SYSTEM_MESSAGE(SystemMessage message) { + super(OPCODE); + this.id = message.id; + } + + @Override + public void write(Lineage2Client conn, ChannelBuffer buffer) { + buffer.writeInt(id); + buffer.writeInt(params.size()); + for (final SystemMessagePacketParameter param : params) { + param.write(conn, buffer); + } + } + + /** + * Adds an string parameter + * + * @param text + * the text + * @return this instance + */ + public final SM_SYSTEM_MESSAGE addString(final String text) { + params.add(new SystemMessagePacketParameter() { + @Override + public void write(Lineage2Client conn, ChannelBuffer buffer) { + buffer.writeInt(TYPE_TEXT); + BufferUtils.writeString(buffer, text); + } + }); + return this; + } + + /** + * Castlename-e.dat
+ * 0-9 Castle names
+ * 21-64 CH names
+ * 81-89 Territory names
+ * 101-121 Fortress names
+ * + * @param fort + * the fort + * @return the {@link SM_SYSTEM_MESSAGE} instance + */ + public final SM_SYSTEM_MESSAGE addFort(final Fort fort) { + params.add(new SystemMessagePacketParameter() { + @Override + public void write(Lineage2Client conn, ChannelBuffer buffer) { + buffer.writeInt(TYPE_CASTLE_NAME); + buffer.writeInt(fort.getID().getID()); + } + }); + return this; + } + + /** + * Adds an number parameter + * + * @param number + * the number + * @return this instance + */ + public final SM_SYSTEM_MESSAGE addNumber(final int number) { + params.add(new SystemMessagePacketParameter() { + @Override + public void write(Lineage2Client conn, ChannelBuffer buffer) { + buffer.writeInt(TYPE_NUMBER); + buffer.writeInt(number); + } + }); + return this; + } + + /** + * Adds an item count parameter + * + * @param number + * the number + * @return this instance + */ + public final SM_SYSTEM_MESSAGE addItemCount(final long number) { + params.add(new SystemMessagePacketParameter() { + @Override + public void write(Lineage2Client conn, ChannelBuffer buffer) { + buffer.writeInt(TYPE_ITEM_NUMBER); + buffer.writeLong(number); + } + }); + return this; + } + + /** + * Adds an the actor name + * + * @param actor + * the actor + * @return this instance + */ + public final SM_SYSTEM_MESSAGE addActorName(final Actor actor) { + // params.add(new SystemMessagePacketParameter() { + // @Override + // public void write(Lineage2Connection conn, ChannelBuffer buffer) { + // // buffer.writeInt(TYPE_TEXT); + // // buffer.writeInt(number); + // // TODO + // } + // }); + return this; + } + + /** + * Adds the item name + * + * @param item + * the item + * @return this instance + */ + public final SM_SYSTEM_MESSAGE addItem(final ItemTemplate item) { + params.add(new SystemMessagePacketParameter() { + @Override + public void write(Lineage2Client conn, ChannelBuffer buffer) { + buffer.writeInt(TYPE_ITEM_NAME); + buffer.writeInt(item.getID().getID()); + } + }); + return this; + } + + /** + * Adds the item name + * + * @param item + * the item + * @return this instance + */ + public final SM_SYSTEM_MESSAGE addItem(final Item item) { + return addItem(item.getTemplateID().getTemplate()); + } + + /** + * Adds the zone name + * + * @param x + * the x + * @param y + * the y + * @param z + * the z + * + * @return this instance + */ + public final SM_SYSTEM_MESSAGE addZoneName(final int x, final int y, + final int z) { + params.add(new SystemMessagePacketParameter() { + @Override + public void write(Lineage2Client conn, ChannelBuffer buffer) { + buffer.writeInt(TYPE_ZONE_NAME); + buffer.writeInt(x); + buffer.writeInt(y); + buffer.writeInt(z); + } + }); + return this; + } + + /** + * @param skill + * the skill template + * @param level + * the skill level + * @return this instance + */ + public final SM_SYSTEM_MESSAGE addSkill(final SkillTemplate skill, + final int level) { + params.add(new SystemMessagePacketParameter() { + @Override + public void write(Lineage2Client conn, ChannelBuffer buffer) { + buffer.writeInt(TYPE_SKILL_NAME); + buffer.writeInt(skill.getID().getID()); + buffer.writeInt(level); + } + }); + return this; + } + + /** + * @param skill + * the skill + * @return this instance + */ + public final SM_SYSTEM_MESSAGE addSkill(final Skill skill) { + return addSkill(skill.getTemplate(), skill.getLevel()); + } + + /** + * Elemental name - 0(Fire) ... + * + * @param type + * the type + * @return the {@link SM_SYSTEM_MESSAGE} instance + */ + public final SM_SYSTEM_MESSAGE addElemntal(final int type) { + params.add(new SystemMessagePacketParameter() { + @Override + public void write(Lineage2Client conn, ChannelBuffer buffer) { + buffer.writeInt(TYPE_ELEMENT_NAME); + buffer.writeInt(type); + } + }); + return this; + } + + /** + * ID from sysstring-e.dat + * + * @param type + * the type + * @return the {@link SM_SYSTEM_MESSAGE} instance + */ + public final SM_SYSTEM_MESSAGE addSystemString(final int type) { + params.add(new SystemMessagePacketParameter() { + @Override + public void write(Lineage2Client conn, ChannelBuffer buffer) { + buffer.writeInt(TYPE_SYSTEM_STRING); + buffer.writeInt(type); + } + }); + return this; + } + + /** + * Instance name from instantzonedata-e.dat + * + * @param type + * id of instance + * @return the {@link SM_SYSTEM_MESSAGE} instance + */ + public final SM_SYSTEM_MESSAGE addInstanceName(final int type) { + params.add(new SystemMessagePacketParameter() { + @Override + public void write(Lineage2Client conn, ChannelBuffer buffer) { + buffer.writeInt(TYPE_INSTANCE_NAME); + buffer.writeInt(type); + } + }); + return this; + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/service/network/NettyNetworkService.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/service/network/NettyNetworkService.java new file mode 100644 index 000000000..8c12dbd02 --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/service/network/NettyNetworkService.java @@ -0,0 +1,204 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +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.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.game.net.Lineage2PipelineFactory; +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 Rogiel + */ +@Depends({ LoggingService.class, ThreadService.class, + BlowfishKeygenService.class, WorldService.class }) +public class NettyNetworkService extends + AbstractConfigurableService 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 clients = CollectionFactory.newSet(); + + /** + * @param injector + * the {@link Guice} {@link Injector} + * @param threadService + * the {@link ThreadService} + */ + @Inject + public NettyNetworkService(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(new Lineage2PipelineFactory(injector, this)); + channel = (ServerChannel) server.bind(config.getListenAddress()); + } + + @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(); + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/service/network/broadcast/BroadcastServiceImpl.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/service/network/broadcast/BroadcastServiceImpl.java new file mode 100644 index 000000000..7844b3be1 --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/service/network/broadcast/BroadcastServiceImpl.java @@ -0,0 +1,385 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.service.network.broadcast; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.Preconditions; +import com.google.inject.Inject; +import com.l2jserver.game.net.packet.server.SM_ACTOR_ATTACK; +import com.l2jserver.game.net.packet.server.SM_ACTOR_CHAT; +import com.l2jserver.game.net.packet.server.SM_ACTOR_DIE; +import com.l2jserver.game.net.packet.server.SM_ACTOR_MOVE; +import com.l2jserver.game.net.packet.server.SM_ACTOR_STATUS_UPDATE; +import com.l2jserver.game.net.packet.server.SM_ACTOR_STATUS_UPDATE.Stat; +import com.l2jserver.game.net.packet.server.SM_CHAR_INFO; +import com.l2jserver.game.net.packet.server.SM_CHAR_INFO_BROADCAST; +import com.l2jserver.game.net.packet.server.SM_CHAR_INFO_EXTRA; +import com.l2jserver.game.net.packet.server.SM_CHAR_INVENTORY; +import com.l2jserver.game.net.packet.server.SM_CHAR_MOVE_TYPE; +import com.l2jserver.game.net.packet.server.SM_CHAR_SHORTCUT_LIST; +import com.l2jserver.game.net.packet.server.SM_CHAR_SHORTCUT_REGISTER; +import com.l2jserver.game.net.packet.server.SM_CHAR_TARGET; +import com.l2jserver.game.net.packet.server.SM_CHAR_TARGET_UNSELECT; +import com.l2jserver.game.net.packet.server.SM_CHAR_TELEPORT; +import com.l2jserver.game.net.packet.server.SM_HTML; +import com.l2jserver.game.net.packet.server.SM_ITEM_GROUND; +import com.l2jserver.game.net.packet.server.SM_ITEM_PICK; +import com.l2jserver.game.net.packet.server.SM_NPC_INFO; +import com.l2jserver.game.net.packet.server.SM_OBJECT_REMOVE; +import com.l2jserver.model.id.object.CharacterID; +import com.l2jserver.model.server.ChatMessage; +import com.l2jserver.model.world.Actor; +import com.l2jserver.model.world.Item; +import com.l2jserver.model.world.L2Character; +import com.l2jserver.model.world.NPC; +import com.l2jserver.model.world.PositionableObject; +import com.l2jserver.model.world.WorldObject; +import com.l2jserver.model.world.actor.event.ActorAttackHitEvent; +import com.l2jserver.model.world.actor.event.ActorDieEvent; +import com.l2jserver.model.world.actor.event.ActorTeleportingEvent; +import com.l2jserver.model.world.actor.event.ActorUnspawnEvent; +import com.l2jserver.model.world.character.event.CharacterCreateShortcutEvent; +import com.l2jserver.model.world.character.event.CharacterEnterWorldEvent; +import com.l2jserver.model.world.character.event.CharacterEvent; +import com.l2jserver.model.world.character.event.CharacterLeaveWorldEvent; +import com.l2jserver.model.world.character.event.CharacterListener; +import com.l2jserver.model.world.character.event.CharacterMoveEvent; +import com.l2jserver.model.world.character.event.CharacterRunningEvent; +import com.l2jserver.model.world.character.event.CharacterStartMovingEvent; +import com.l2jserver.model.world.character.event.CharacterTargetDeselectedEvent; +import com.l2jserver.model.world.character.event.CharacterTargetSelectedEvent; +import com.l2jserver.model.world.character.event.CharacterWalkingEvent; +import com.l2jserver.model.world.item.ItemDropEvent; +import com.l2jserver.model.world.item.ItemPickEvent; +import com.l2jserver.model.world.npc.event.NPCSpawnEvent; +import com.l2jserver.model.world.npc.event.NPCTalkEvent; +import com.l2jserver.model.world.player.event.PlayerTeleportedEvent; +import com.l2jserver.service.AbstractService; +import com.l2jserver.service.AbstractService.Depends; +import com.l2jserver.service.game.chat.ChatChannel; +import com.l2jserver.service.game.chat.ChatChannelListener; +import com.l2jserver.service.game.chat.ChatMessageType; +import com.l2jserver.service.game.chat.ChatService; +import com.l2jserver.service.game.world.WorldService; +import com.l2jserver.service.game.world.event.FilteredWorldListener; +import com.l2jserver.service.game.world.event.WorldEvent; +import com.l2jserver.service.game.world.event.WorldEventDispatcherService; +import com.l2jserver.service.game.world.event.WorldListener; +import com.l2jserver.service.game.world.filter.impl.KnownListFilter; +import com.l2jserver.service.game.world.filter.impl.KnownListUpdateFilter; +import com.l2jserver.service.network.NetworkService; +import com.l2jserver.service.network.model.Lineage2Client; +import com.l2jserver.service.network.model.SystemMessage; +import com.l2jserver.util.geometry.Point3D; + +/** + * @author Rogiel + */ +@Depends({ NetworkService.class, WorldService.class }) +public class BroadcastServiceImpl extends AbstractService implements + BroadcastService { + /** + * The logger + */ + private final Logger log = LoggerFactory.getLogger(this.getClass()); + + /** + * The world service + */ + private final WorldService worldService; + /** + * The {@link ChatService} + */ + private final ChatService chatService; + /** + * The {@link ChatService} + */ + private final NetworkService networkService; + + /** + * The world service event dispatcher + */ + private final WorldEventDispatcherService eventDispatcher; + + /** + * @param worldService + * the world service + * @param chatService + * the chat service + * @param networkService + * the network service + * @param eventDispatcher + * the world service event disptacher + */ + @Inject + public BroadcastServiceImpl(WorldService worldService, + ChatService chatService, NetworkService networkService, + WorldEventDispatcherService eventDispatcher) { + this.worldService = worldService; + this.chatService = chatService; + this.networkService = networkService; + this.eventDispatcher = eventDispatcher; + } + + @Override + public void broadcast(final L2Character character) { + Preconditions.checkNotNull(character, "character"); + final Lineage2Client conn = networkService.discover(character.getID()); + Preconditions.checkNotNull(conn, "conn"); + final CharacterID id = character.getID(); + + log.debug("Registering character broadcast listeners"); + + // event broadcast listener + // this listener will be filtered so that only interesting events are + // dispatched, once a event arrives will be possible to check check if + // the given event will be broadcasted or not + final WorldListener neighborListener = new FilteredWorldListener( + new KnownListFilter(character)) { + @Override + protected boolean dispatch(WorldEvent e, PositionableObject object) { + log.debug("Broadcast event received: {}", e); + if (e instanceof NPCSpawnEvent || e instanceof ItemDropEvent) { + broadcast(conn, e.getObject()); + } else if (e instanceof CharacterMoveEvent) { + final CharacterMoveEvent evt = (CharacterMoveEvent) e; + conn.write(new SM_ACTOR_MOVE((L2Character) object, evt + .getPoint().getCoordinate())); + } else if (e instanceof PlayerTeleportedEvent + || e instanceof CharacterEnterWorldEvent) { + broadcast(conn, e.getObject()); + } else if (e instanceof ItemPickEvent) { + conn.write(new SM_ITEM_PICK(((ItemPickEvent) e) + .getCharacter(), (Item) object)); + conn.write(new SM_OBJECT_REMOVE(object)); + } else if (e instanceof ActorTeleportingEvent + || e instanceof CharacterLeaveWorldEvent + || e instanceof ActorUnspawnEvent) { + // object is now out of sight + conn.write(new SM_OBJECT_REMOVE(object)); + } else if (e instanceof CharacterWalkingEvent) { + conn.write(new SM_CHAR_MOVE_TYPE( + ((CharacterWalkingEvent) e).getCharacter())); + } else if (e instanceof CharacterRunningEvent) { + conn.write(new SM_CHAR_MOVE_TYPE( + ((CharacterRunningEvent) e).getCharacter())); + } else if (e instanceof ActorDieEvent) { + conn.write(new SM_ACTOR_DIE(((ActorDieEvent) e).getActor())); + } + // keep listener alive + return true; + } + }; + // add the global listener + eventDispatcher.addListener(neighborListener); + // this listener is bound directly to the character, no need for filters + // or any other test inside listener + final WorldListener sendPacketListener = new WorldListener() { + @Override + public boolean dispatch(WorldEvent e) { + log.debug("Broadcast event received: {}", e); + if (e instanceof CharacterMoveEvent) { + final CharacterMoveEvent evt = (CharacterMoveEvent) e; + // process update known list + broadcastUpdate(conn, evt.getCharacter(), evt.getPoint()); + } else if (e instanceof CharacterEnterWorldEvent) { + clientEnterWorld(conn, (CharacterEnterWorldEvent) e); + } else if (e instanceof CharacterStartMovingEvent) { + conn.write(new SM_ACTOR_MOVE( + ((CharacterStartMovingEvent) e).getCharacter(), + ((CharacterStartMovingEvent) e).getPoint() + .getCoordinate())); + } else if (e instanceof CharacterTargetSelectedEvent) { + final CharacterTargetSelectedEvent evt = (CharacterTargetSelectedEvent) e; + final Actor target = evt.getTarget(); + final L2Character character = evt.getCharacter(); + conn.write(new SM_CHAR_TARGET(target, character.getLevel() + - target.getLevel())); + if (target instanceof NPC) { + final NPC mob = (NPC) target; + conn.write(new SM_ACTOR_STATUS_UPDATE(mob).add( + Stat.MAX_HP, + (int) mob.getTemplate().getInfo().getStats() + .getHp().getMax()).add(Stat.HP, + (int) mob.getHP())); + } + } else if (e instanceof CharacterTargetDeselectedEvent) { + conn.write(new SM_CHAR_TARGET_UNSELECT( + ((CharacterTargetDeselectedEvent) e).getCharacter())); + } else if (e instanceof PlayerTeleportedEvent) { + final L2Character character = (L2Character) ((PlayerTeleportedEvent) e) + .getPlayer(); + conn.write(new SM_CHAR_INFO(character)); + //conn.write(new SM_CHAR_INFO_EXTRA(character)); not sure if interlude has this packet. + broadcastAll(conn, character); + } else if (e instanceof ActorAttackHitEvent) { + conn.write(new SM_ACTOR_ATTACK(((ActorAttackHitEvent) e) + .getHit())); + conn.sendSystemMessage(SystemMessage.YOU_DID_S1_DMG, + (int) ((ActorAttackHitEvent) e).getHit() + .getDamage()); + } else if (e instanceof CharacterWalkingEvent + || e instanceof CharacterRunningEvent) { + conn.write(new SM_CHAR_MOVE_TYPE((L2Character) e + .getObject())); + } else if (e instanceof ActorTeleportingEvent) { + final ActorTeleportingEvent evt = (ActorTeleportingEvent) e; + conn.write(new SM_CHAR_TELEPORT((L2Character) evt + .getActor(), evt.getPoint())); + } else if (e instanceof NPCTalkEvent) { + conn.write(new SM_HTML(((NPCTalkEvent) e).getNPC(), + ((NPCTalkEvent) e).getHtml())); + conn.sendActionFailed(); + } else if (e instanceof CharacterCreateShortcutEvent) { + conn.write(new SM_CHAR_SHORTCUT_REGISTER( + ((CharacterCreateShortcutEvent) e).getShortcut())); + } + // keep listener alive + return true; + } + }; + // add listener only for this character + eventDispatcher.addListener(id, sendPacketListener); + } + + /** + * Broadcast all nearby objects to this client + * + * @param conn + * the connection + * @param character + * the character + */ + private void broadcastAll(Lineage2Client conn, L2Character character) { + log.debug("Broadcasting all near objects to {}", character); + for (final WorldObject o : worldService.iterable(new KnownListFilter( + character))) { + broadcast(conn, o); + } + } + + /** + * Broadcast new nearby objects to this client. Will only broadcast if the + * object was out-of-range before and now is in range. + * + * @param conn + * the connection + * @param character + * the character + * @param point + * the old point + */ + private void broadcastUpdate(Lineage2Client conn, L2Character character, + Point3D point) { + log.debug("Broadcasting only new near objects to {}", character); + for (final WorldObject o : worldService + .iterable(new KnownListUpdateFilter(character, point))) { + broadcast(conn, o); + } + } + + /** + * Broadcast an object to this client + * + * @param conn + * the connection + * @param o + * the object to be broadcasted + */ + private void broadcast(Lineage2Client conn, WorldObject o) { + log.debug("Broadcasting {} to {}", o, conn); + if (o instanceof NPC) { + conn.write(new SM_NPC_INFO((NPC) o)); + } else if (o instanceof L2Character) { + conn.write(new SM_CHAR_INFO_BROADCAST((L2Character) o)); + } else if (o instanceof Item) { + conn.write(new SM_ITEM_GROUND((Item) o)); + } + } + + /** + * Sends required packets for a client to enter the game virtual world + * + * @param conn + * the Lineage 2 connection + * @param e + * the event + */ + private void clientEnterWorld(final Lineage2Client conn, + CharacterEnterWorldEvent e) { + final L2Character character = e.getCharacter(); + final CharacterID id = character.getID(); + + // chat listener + final ChatChannelListener globalChatListener = new ChatChannelListener() { + @Override + public void onMessage(ChatChannel channel, ChatMessage message) { + conn.write(new SM_ACTOR_CHAT(message.getSender().getObject(), + ChatMessageType.ALL, message.getMessage())); + } + }; + final ChatChannelListener tradeChatListener = new ChatChannelListener() { + @Override + public void onMessage(ChatChannel channel, ChatMessage message) { + conn.write(new SM_ACTOR_CHAT(message.getSender().getObject(), + ChatMessageType.TRADE, message.getMessage())); + } + }; + + // leave world event + eventDispatcher.addListener(id, new CharacterListener() { + @Override + protected boolean dispatch(CharacterEvent e) { + if (!(e instanceof CharacterLeaveWorldEvent)) + return true; + + log.debug( + "Character {} is leaving world, removing chat listeners", + character); + + // remove chat listeners + chatService.getGlobalChannel().removeMessageListener( + globalChatListener); + chatService.getTradeChannel().removeMessageListener( + tradeChatListener); + + // we can kill this listener now + return false; + } + }); + + // register global chat listener + chatService.getGlobalChannel().addMessageListener(globalChatListener); + chatService.getTradeChannel().addMessageListener(tradeChatListener); + + log.debug("Sending greeting message to client"); + conn.sendSystemMessage(SystemMessage.WELCOME_TO_LINEAGE); + conn.sendMessage("This an an development version for l2jserver 2.0"); + conn.sendMessage("Please note that many of the features are not yet implemented."); + + // send this user information + log.debug("Sending character information packets"); + conn.write(new SM_CHAR_INFO(e.getCharacter())); +// conn.write(new SM_CHAR_INFO_EXTRA(e.getCharacter())); interlude doesn't have this? + conn.write(new SM_CHAR_INVENTORY(e.getCharacter().getInventory())); + conn.write(new SM_CHAR_SHORTCUT_LIST(e.getCharacter().getShortcuts())); + + broadcastAll(conn, character); + } +} diff --git a/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/service/network/gameguard/GameGuardServiceImpl.java b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/service/network/gameguard/GameGuardServiceImpl.java new file mode 100644 index 000000000..425d8e1a0 --- /dev/null +++ b/l2jserver2-gameserver/l2jserver2-gameserver-interlude/src/main/java/com/l2jserver/service/network/gameguard/GameGuardServiceImpl.java @@ -0,0 +1,174 @@ +/* + * This file is part of l2jserver2 . + * + * 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 . + */ +package com.l2jserver.service.network.gameguard; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Map; +import java.util.concurrent.Future; + +import org.jboss.netty.channel.ChannelFuture; +import org.jboss.netty.channel.ChannelFutureListener; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.util.concurrent.AbstractFuture; +import com.google.inject.Inject; +import com.l2jserver.game.net.packet.server.SM_GG_QUERY; +import com.l2jserver.model.world.L2Character; +import com.l2jserver.service.AbstractService; +import com.l2jserver.service.AbstractService.Depends; +import com.l2jserver.service.ServiceStartException; +import com.l2jserver.service.ServiceStopException; +import com.l2jserver.service.game.chat.ChatService; +import com.l2jserver.service.network.NetworkService; +import com.l2jserver.service.network.model.Lineage2Client; +import com.l2jserver.util.factory.CollectionFactory; + +/** + * Default implementation for {@link GameGuardService} + * + * @author Rogiel + */ +@Depends({ NetworkService.class }) +public class GameGuardServiceImpl extends AbstractService implements + GameGuardService { + /** + * The logger + */ + private final Logger log = LoggerFactory.getLogger(this.getClass()); + + /** + * The static key used to validate game guards + */ + private static final int[] STATIC_KEY = { 0x27533DD9, 0x2E72A51D, + 0x2017038B, 0xC35B1EA3 }; + /** + * The valid GG SHA1 response -- for a single key, the answer must be always + * the same + */ + @SuppressWarnings("unused") + private static final byte[] STATIC_KEY_VALIDATION = { (byte) 0x88, 0x40, + 0x1c, (byte) 0xa7, (byte) 0x83, 0x42, (byte) 0xe9, 0x15, + (byte) 0xde, (byte) 0xc3, 0x68, (byte) 0xf6, 0x2d, 0x23, + (byte) 0xf1, 0x3f, (byte) 0xee, 0x68, 0x5b, (byte) 0xc5 }; + + /** + * The {@link ChatService} + */ + private final NetworkService networkService; + + /** + * The map containing all pending futures + */ + private Map futures; + /** + * The {@link MessageDigest} for SHA-1. + *

+ * Access must be synchronized externally. + */ + @SuppressWarnings("unused") + private MessageDigest digester; + + /** + * @param networkService + * the network service + */ + @Inject + private GameGuardServiceImpl(NetworkService networkService) { + this.networkService = networkService; + } + + @Override + protected void doStart() throws ServiceStartException { + futures = CollectionFactory.newMap(); + try { + digester = MessageDigest.getInstance("SHA"); + } catch (NoSuchAlgorithmException e) { + throw new ServiceStartException(e); + } + } + + @Override + public Future query(final L2Character character) { + log.debug("Quering client for GameGuard authentication key"); + final Lineage2Client conn = networkService.discover(character.getID()); + conn.write(new SM_GG_QUERY(STATIC_KEY)).addListener( + new ChannelFutureListener() { + @Override + public void operationComplete(ChannelFuture future) + throws Exception { + if (future.getCause() != null) { + futures.remove(conn); + } + } + }); + final GGFuture future = new GGFuture(); + futures.put(conn, future); + return future; + } + + @Override + public GameGuardResponse key(Lineage2Client conn, byte[] key) { + log.debug("GameGuard authentication key received for {}", conn); + + final GGFuture future = futures.remove(conn); + final boolean validated = validate(conn, key); + final GameGuardResponse response = (validated ? GameGuardResponse.VALID + : GameGuardResponse.INVALID); + if (future != null) + future.set(response); + return response; + } + + /** + * Creates a SHA1 sum of the key and checks is validity. + * + * @param conn + * the connection + * @param key + * the key + * @return true if key is valid + */ + private boolean validate(Lineage2Client conn, byte[] key) { + // synchronized (digester) { + // return Arrays.equals(VALID_KEY_SHA1, digester.digest(key)); + // } + return true; + } + + @Override + protected void doStop() throws ServiceStopException { + futures = null; + digester = null; + } + + /** + * The GGFuture awaits for the + * {@link com.l2jserver.service.network.gameguard.GameGuardService.GameGuardResponse} + * + * @author Rogiel + */ + private class GGFuture extends AbstractFuture implements + Future { + @Override + protected boolean set(GameGuardResponse value) { + // protected wrapper + return super.set(value); + } + } +}