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

Downgrading to support Interlude

This commit is contained in:
Modestas Goncarovas
2012-04-18 04:26:50 +01:00
parent 1084905350
commit 907495f623
91 changed files with 9768 additions and 0 deletions

View File

@@ -0,0 +1,3 @@
/services.xml
bin/
*.class

View File

@@ -0,0 +1,136 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<services xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<!-- DAO Module configuration -->
<dao module="com.l2jserver.service.database.OrientDBDAOModule" />
<!-- ###################################################################### -->
<!-- ########################### CORE SERVICES ############################ -->
<!-- ###################################################################### -->
<!-- Those services provide basic core features and are required for server
startup process -->
<service interface="com.l2jserver.service.database.DatabaseService"
implementation="com.l2jserver.service.database.GameServerOrientDatabaseService">
<!-- Whether the database schema should be updated at startup -->
<!-- Slows down a bit at start time, but guarantees consistency -->
<!-- Recommended to only be enabled after an server update -->
<schema automaticUpdate="true" />
<!-- The connection URL defines where the database data is stored -->
<connection url="local:data/database">
<!-- Database authentication. Should not be touched unless you know what
you are doing! -->
<authentication username="admin" password="admin" />
</connection>
</service>
<service interface="com.l2jserver.service.core.vfs.VFSService"
implementation="com.l2jserver.service.core.vfs.TrueZipVFSService">
<!-- Configures the root of the server data. Where all the files are placed. -->
<fileSystem root="./">
<!-- The "data file system" location. There, templates, static data and
several other important files are located. This can be a zip or a directory. -->
<!-- The "data file system" is relative to the file system root. -->
<data root="data.zip" />
</fileSystem>
</service>
<service interface="com.l2jserver.service.core.threading.ThreadService"
implementation="com.l2jserver.service.core.threading.ThreadServiceImpl" />
<service interface="com.l2jserver.service.configuration.ConfigurationService"
implementation="com.l2jserver.service.configuration.XMLConfigurationService" />
<service interface="com.l2jserver.service.cache.CacheService"
implementation="com.l2jserver.service.cache.SoftCacheService" />
<service interface="com.l2jserver.service.core.logging.LoggingService"
implementation="com.l2jserver.service.core.logging.Log4JLoggingService">
<logger name="" level="ERROR" />
<logger name="com.l2jserver" level="INFO" />
</service>
<!-- ###################################################################### -->
<!-- ########################### GAME SERVICES ############################ -->
<!-- ###################################################################### -->
<!-- Those services provide all the in-game features and most of them are
required for players to be able to login in the server -->
<service interface="com.l2jserver.service.game.world.WorldIDService"
implementation="com.l2jserver.service.game.world.CachedWorldIDService" />
<service interface="com.l2jserver.service.game.map.pathing.PathingService"
implementation="com.l2jserver.service.game.map.pathing.MapperPathingService" />
<service interface="com.l2jserver.service.game.scripting.ScriptingService"
implementation="com.l2jserver.service.game.scripting.ScriptingServiceImpl" />
<service interface="com.l2jserver.service.game.chat.ChatService"
implementation="com.l2jserver.service.game.chat.SimpleChatService" />
<service interface="com.l2jserver.service.game.chat.ChatLoggingService"
implementation="com.l2jserver.service.game.chat.DatabaseChatLoggingService" />
<service interface="com.l2jserver.service.game.admin.AdministratorService"
implementation="com.l2jserver.service.game.admin.AdministratorServiceImpl" />
<service interface="com.l2jserver.service.game.spawn.SpawnService"
implementation="com.l2jserver.service.game.spawn.SpawnServiceImpl" />
<service interface="com.l2jserver.service.game.character.CharacterService"
implementation="com.l2jserver.service.game.character.CharacterServiceImpl">
<!-- Defines the restrictions for character creation -->
<creation allow="true" allowed-races="HUMAN|ELF|DARK_ELF|ORC|DWARF"
allowed-genders="MALE|FEMALE">
<!-- The maximum amount of characters per account -->
<limits max-per-account="8" />
</creation>
</service>
<service interface="com.l2jserver.service.game.character.ShortcutService"
implementation="com.l2jserver.service.game.character.ShortcutServiceImpl" />
<service interface="com.l2jserver.service.game.AttackService"
implementation="com.l2jserver.service.game.AttackServiceImpl" />
<service interface="com.l2jserver.service.game.npc.NPCService"
implementation="com.l2jserver.service.game.npc.NPCServiceImpl" />
<service interface="com.l2jserver.service.game.item.ItemService"
implementation="com.l2jserver.service.game.item.ItemServiceImpl">
<!-- Whether drops are persisted in the database. Valid modes are: -->
<!-- ALL - All types of drops are stored into the database -->
<!-- CHARACTER_ONLY - Only items dropped by characters are stored in the
database -->
<!-- NONE - None of the dropped items are saved into the database -->
<drop persistent="ALL" />
</service>
<service interface="com.l2jserver.service.game.world.WorldService"
implementation="com.l2jserver.service.game.world.WorldServiceImpl" />
<service
interface="com.l2jserver.service.game.world.event.WorldEventDispatcherService"
implementation="com.l2jserver.service.game.world.event.WorldEventDispatcherServiceImpl">
<!-- The amount of dispatching threads to use. You should not set it to
a value higher than the number of processor cores on your system. Doing so,
might result in performance loss instead of increase. -->
<!-- If you wish the system to automatically determine the number of cores
in the system and configure the system accordingly, set it to 0 -->
<threading count="0" />
</service>
<!-- Template service configuration -->
<service interface="com.l2jserver.service.game.template.TemplateService"
implementation="com.l2jserver.service.game.template.XMLTemplateService">
<!-- The root where template data is located. Relative to the "data file
system" -->
<templates root="template/" />
<!-- Whether the templates XML schemas should be validated before loading.
This should be on, unless you know what you are doing! -->
<schema validation="true" />
</service>
<!-- ####################################################################### -->
<!-- ########################## NETWORK SERVICES ########################### -->
<!-- ####################################################################### -->
<!-- Those services all network related services that will communicate the
server software to the player computer running the game client. Although
not required, without them, becomes impossible to connect to the server in
order to play the game. -->
<service interface="com.l2jserver.service.network.NetworkService"
implementation="com.l2jserver.service.network.NettyNetworkService">
<!-- The port in which the server should listen for incoming connections -->
<!-- NOTE: this port must be open manually on any firewall or router that
is between you and other players. If you wish to play on the same machine
you normally don't need to change anything here nor in the firewall. -->
<server listen="0.0.0.0:7777" />
</service>
<service interface="com.l2jserver.service.network.keygen.BlowfishKeygenService"
implementation="com.l2jserver.service.network.keygen.SecureBlowfishKeygenService" />
<service interface="com.l2jserver.service.network.gameguard.GameGuardService"
implementation="com.l2jserver.service.network.gameguard.GameGuardServiceImpl" />
<service interface="com.l2jserver.service.network.broadcast.BroadcastService"
implementation="com.l2jserver.service.network.broadcast.BroadcastServiceImpl" />
</services>

View File

@@ -0,0 +1,51 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>l2jserver2-gameserver</artifactId>
<groupId>com.l2jserver</groupId>
<version>0.0.2-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<artifactId>l2jserver2-gameserver-interlude</artifactId>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptors>
<descriptor>src/main/assembly/distribution-mysql5-bin.xml</descriptor>
<descriptor>src/main/assembly/distribution-orientdb-bin.xml</descriptor>
<descriptor>src/main/assembly/distribution-h2-bin.xml</descriptor>
<descriptor>src/main/assembly/distribution-derby-bin.xml</descriptor>
<descriptor>src/main/assembly/distribution-src.xml</descriptor>
</descriptors>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>libs/</classpathPrefix>
<mainClass>com.l2jserver.L2JGameServerMain</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>com.l2jserver</groupId>
<artifactId>l2jserver2-gameserver-core</artifactId>
<version>0.0.2-SNAPSHOT</version>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,154 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!-- This file should be copied as "services.xml" and configured according
to your needs. Since "services.xml" has been added to ".gitignore", this
means that your password won't be sent to the repository when you make a
commit. -->
<!-- IMPORTANT NOTE: Do not forget to edit "distribution/services.xml" with
new services definitions. Only that file is included in the server's binary
distributions -->
<services xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<!-- DAO Module configuration -->
<dao module="com.l2jserver.service.database.JDBCDAOModule" />
<!-- ###################################################################### -->
<!-- ########################### CORE SERVICES ############################ -->
<!-- ###################################################################### -->
<!-- Those services provide basic core features and are required for server
startup process -->
<service interface="com.l2jserver.service.database.DatabaseService"
implementation="com.l2jserver.service.database.GameServerJDBCDatabaseService">
<!-- Whether the database schema should be updated at startup -->
<!-- Slows down a bit at start time, but guarantees consistency -->
<!-- Enabled for development servers -->
<schema automaticUpdate="true" />
<!-- Defines the JDBC connection URL -->
<connection url="jdbc:mysql://localhost/l2jserver2">
<!-- The database authentication (username and password) -->
<authentication username="l2jserver2" password="changeme" />
<!-- Specifies the database engine to use - will load JDBC driver and
SQL templates -->
<engine class="com.l2jserver.service.database.sql.MySQLDatabaseEngine" />
<!-- Defines the database connection pool limits -->
<pool max-active="20" max-idle="20" min-idle="5" />
</connection>
</service>
<service interface="com.l2jserver.service.core.vfs.VFSService"
implementation="com.l2jserver.service.core.vfs.TrueZipVFSService">
<!-- Configures the root of the server data. Where all the files are placed. -->
<fileSystem root="../">
<!-- The "data file system" location. There, templates, static data and
several other important files are located. This can be a zip or a directory. -->
<!-- The "data file system" is relative to the file system root. -->
<data root="data/" />
</fileSystem>
</service>
<service interface="com.l2jserver.service.core.threading.ThreadService"
implementation="com.l2jserver.service.core.threading.ThreadServiceImpl" />
<service interface="com.l2jserver.service.configuration.ConfigurationService"
implementation="com.l2jserver.service.configuration.XMLConfigurationService" />
<service interface="com.l2jserver.service.cache.CacheService"
implementation="com.l2jserver.service.cache.SoftCacheService" />
<service interface="com.l2jserver.service.core.logging.LoggingService"
implementation="com.l2jserver.service.core.logging.Log4JLoggingService">
<logger name="" level="ERROR" />
<logger name="com.l2jserver" level="INFO" />
<logger name="com.l2jserver.service.game.template.XMLTemplateService"
level="INFO" />
<logger name="com.l2jserver.service.cache" level="INFO" />
<logger
name="com.l2jserver.service.database.sql.AbstractSQLDatabaseService"
level="INFO" />
<logger name="com.l2jserver.service.game.world.CachedWorldIDService"
level="INFO" />
<logger name="com.l2jserver.model.id.object.allocator.BitSetIDAllocator"
level="INFO" />
</service>
<!-- ###################################################################### -->
<!-- ########################### GAME SERVICES ############################ -->
<!-- ###################################################################### -->
<!-- Those services provide all the in-game features and most of them are
required for players to be able to login in the server -->
<service interface="com.l2jserver.service.game.world.WorldIDService"
implementation="com.l2jserver.service.game.world.CachedWorldIDService" />
<service interface="com.l2jserver.service.game.map.pathing.PathingService"
implementation="com.l2jserver.service.game.map.pathing.MapperPathingService" />
<service interface="com.l2jserver.service.game.scripting.ScriptingService"
implementation="com.l2jserver.service.game.scripting.ScriptingServiceImpl" />
<service interface="com.l2jserver.service.game.chat.ChatService"
implementation="com.l2jserver.service.game.chat.SimpleChatService" />
<service interface="com.l2jserver.service.game.chat.ChatLoggingService"
implementation="com.l2jserver.service.game.chat.DatabaseChatLoggingService" />
<service interface="com.l2jserver.service.game.admin.AdministratorService"
implementation="com.l2jserver.service.game.admin.AdministratorServiceImpl" />
<service interface="com.l2jserver.service.game.spawn.SpawnService"
implementation="com.l2jserver.service.game.spawn.SpawnServiceImpl" />
<service interface="com.l2jserver.service.game.character.CharacterService"
implementation="com.l2jserver.service.game.character.CharacterServiceImpl">
<!-- Defines the restrictions for character creation -->
<creation allow="true" allowed-races="HUMAN|ELF|DARK_ELF|ORC|DWARF|KAMAEL"
allowed-genders="MALE|FEMALE">
<!-- The maximum amount of characters per account -->
<limits max-per-account="8" />
</creation>
</service>
<service interface="com.l2jserver.service.game.character.ShortcutService"
implementation="com.l2jserver.service.game.character.ShortcutServiceImpl" />
<service interface="com.l2jserver.service.game.AttackService"
implementation="com.l2jserver.service.game.AttackServiceImpl" />
<service interface="com.l2jserver.service.game.npc.NPCService"
implementation="com.l2jserver.service.game.npc.NPCServiceImpl" />
<service interface="com.l2jserver.service.game.item.ItemService"
implementation="com.l2jserver.service.game.item.ItemServiceImpl">
<!-- Whether drops are persisted in the database. Valid modes are: -->
<!-- ALL - All types of drops are stored into the database -->
<!-- CHARACTER_ONLY - Only items dropped by characters are stored in the
database -->
<!-- NONE - None of the dropped items are saved into the database -->
<drop persistent="ALL" />
</service>
<service interface="com.l2jserver.service.game.world.WorldService"
implementation="com.l2jserver.service.game.world.WorldServiceImpl" />
<service
interface="com.l2jserver.service.game.world.event.WorldEventDispatcherService"
implementation="com.l2jserver.service.game.world.event.WorldEventDispatcherServiceImpl">
<!-- The amount of dispatching threads to use. You should not set it to
a value higher than the number of processor cores on your system. Doing so,
might result in performance loss instead of increase. -->
<!-- If you wish the system to automatically determine the number of cores
in the system and configure the system accordingly, set it to 0 -->
<threading count="0" />
</service>
<service interface="com.l2jserver.service.game.template.TemplateService"
implementation="com.l2jserver.service.game.template.XMLTemplateService">
<!-- The root where template data is located. Relative to the "data file
system" -->
<templates root="template/" />
<!-- Whether the templates XML schemas should be validated before loading.
This should be on, unless you know what you are doing! -->
<schema validation="true" />
</service>
<!-- ####################################################################### -->
<!-- ########################## NETWORK SERVICES ########################### -->
<!-- ####################################################################### -->
<!-- Those services all network related services that will communicate the
server software to the player computer running the game client. Although
not required, without them, becomes impossible to connect to the server in
order to play the game. -->
<service interface="com.l2jserver.service.network.NetworkService"
implementation="com.l2jserver.service.network.NettyNetworkService">
<!-- The port in which the server should listen for incoming connections -->
<!-- NOTE: this port must be open manually on any firewall or router that
is between you and other players. If you wish to play on the same machine
you normally don't need to change anything here nor in the firewall. -->
<server listen="0.0.0.0:7777" />
</service>
<service interface="com.l2jserver.service.network.keygen.BlowfishKeygenService"
implementation="com.l2jserver.service.network.keygen.SecureBlowfishKeygenService" />
<service interface="com.l2jserver.service.network.gameguard.GameGuardService"
implementation="com.l2jserver.service.network.gameguard.GameGuardServiceImpl" />
<service interface="com.l2jserver.service.network.broadcast.BroadcastService"
implementation="com.l2jserver.service.network.broadcast.BroadcastServiceImpl" />
</services>

View File

@@ -0,0 +1,42 @@
<component
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/component/1.1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/component/1.1.2 http://maven.apache.org/xsd/component-1.1.2.xsd">
<fileSets>
<fileSet>
<directory>${project.parent.basedir}/distribution</directory>
<outputDirectory>/</outputDirectory>
</fileSet>
<fileSet>
<directory>${project.basedir}/distribution</directory>
<outputDirectory>/</outputDirectory>
</fileSet>
</fileSets>
<files>
<file>
<source>${project.build.directory}/${project.artifactId}-${project.version}.jar</source>
<outputDirectory>/</outputDirectory>
<destName>l2jserver2.jar</destName>
<fileMode>0755</fileMode>
</file>
<file>
<source>${project.parent.build.directory}/${project.parent.artifactId}-${project.version}-data.zip</source>
<outputDirectory>/</outputDirectory>
<destName>data.zip</destName>
</file>
</files>
<dependencySets>
<dependencySet>
<outputDirectory>/libs</outputDirectory>
<useProjectArtifact>false</useProjectArtifact>
<unpack>false</unpack>
<scope>runtime</scope>
<excludes>
<exclude>mysql:*</exclude>
<exclude>com.orientechnologies:*</exclude>
<exclude>com.h2database:*</exclude>
<exclude>org.apache.derby:*</exclude>
</excludes>
</dependencySet>
</dependencySets>
</component>

View File

@@ -0,0 +1,24 @@
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
<id>derby-bin</id>
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>true</includeBaseDirectory>
<componentDescriptors>
<componentDescriptor>src/main/assembly/distribution-bin.xml</componentDescriptor>
</componentDescriptors>
<dependencySets>
<dependencySet>
<outputDirectory>/libs</outputDirectory>
<useProjectArtifact>false</useProjectArtifact>
<unpack>false</unpack>
<scope>runtime</scope>
<includes>
<include>org.apache.derby:*</include>
</includes>
</dependencySet>
</dependencySets>
</assembly>

View File

@@ -0,0 +1,24 @@
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
<id>h2-bin</id>
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>true</includeBaseDirectory>
<componentDescriptors>
<componentDescriptor>src/main/assembly/distribution-bin.xml</componentDescriptor>
</componentDescriptors>
<dependencySets>
<dependencySet>
<outputDirectory>/libs</outputDirectory>
<useProjectArtifact>false</useProjectArtifact>
<unpack>false</unpack>
<scope>runtime</scope>
<includes>
<include>com.h2database:*</include>
</includes>
</dependencySet>
</dependencySets>
</assembly>

View File

@@ -0,0 +1,24 @@
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
<id>mysql5-bin</id>
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>true</includeBaseDirectory>
<componentDescriptors>
<componentDescriptor>src/main/assembly/distribution-bin.xml</componentDescriptor>
</componentDescriptors>
<dependencySets>
<dependencySet>
<outputDirectory>/libs</outputDirectory>
<useProjectArtifact>false</useProjectArtifact>
<unpack>false</unpack>
<scope>runtime</scope>
<includes>
<include>mysql:*</include>
</includes>
</dependencySet>
</dependencySets>
</assembly>

View File

@@ -0,0 +1,24 @@
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
<id>orientdb-bin</id>
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>true</includeBaseDirectory>
<componentDescriptors>
<componentDescriptor>src/main/assembly/distribution-bin.xml</componentDescriptor>
</componentDescriptors>
<dependencySets>
<dependencySet>
<outputDirectory>/libs</outputDirectory>
<useProjectArtifact>false</useProjectArtifact>
<unpack>false</unpack>
<scope>runtime</scope>
<includes>
<include>com.orientechnologies:*</include>
</includes>
</dependencySet>
</dependencySets>
</assembly>

View File

@@ -0,0 +1,32 @@
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
<id>src</id>
<formats>
<format>zip</format>
</formats>
<baseDirectory></baseDirectory>
<fileSets>
<fileSet>
<directory>${project.basedir}</directory>
<outputDirectory>/</outputDirectory>
<includes>
<include>data/**</include>
<include>src/**</include>
</includes>
</fileSet>
<fileSet>
<directory>${project.basedir}/dist</directory>
<outputDirectory>/</outputDirectory>
</fileSet>
</fileSets>
<dependencySets>
<dependencySet>
<outputDirectory>/libs</outputDirectory>
<useProjectArtifact>true</useProjectArtifact>
<unpack>false</unpack>
<scope>runtime</scope>
</dependencySet>
</dependencySets>
</assembly>

View File

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

View File

@@ -0,0 +1,101 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net;
import 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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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;
}
}

View File

@@ -0,0 +1,109 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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;
}
}

View File

@@ -0,0 +1,109 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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 <tt>key</tt>
*
* @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;
}
}

View File

@@ -0,0 +1,61 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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));
}
}

View File

@@ -0,0 +1,41 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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;
}
}

View File

@@ -0,0 +1,226 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.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.
* <p>
* Note that some packets have an additional opcode. This class also handle
* those cases.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
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 <tt>type</tt>
*
* @param type
* the packet type
* @return the created packet
*/
private ClientPacket createPacket(Class<? extends ClientPacket> type) {
if (type == null)
return null;
return injector.getInstance(type);
}
/**
* Discovers the packet type
*
* @param buffer
* the buffer
* @return the packet class
*/
private Class<? extends ClientPacket> 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;
}
}

View File

@@ -0,0 +1,77 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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;
}
}

View File

@@ -0,0 +1,140 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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", "<br>").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();
}
}
}

View File

@@ -0,0 +1,58 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.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 <a href="http://www.rogiel.com">Rogiel</a>
*
*/
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;
}
}

View File

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

View File

@@ -0,0 +1,94 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.client;
import java.util.StringTokenizer;
import org.jboss.netty.buffer.ChannelBuffer;
import 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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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
}
}

View File

@@ -0,0 +1,145 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.client;
import java.util.List;
import org.jboss.netty.buffer.ChannelBuffer;
import com.google.inject.Inject;
import com.l2jserver.game.net.packet.server.SM_CHAR_LIST;
import com.l2jserver.model.dao.CharacterDAO;
import com.l2jserver.model.id.AccountID;
import com.l2jserver.model.id.provider.AccountIDProvider;
import com.l2jserver.model.world.L2Character;
import com.l2jserver.service.network.model.Lineage2Client;
import com.l2jserver.service.network.model.Lineage2Session;
import com.l2jserver.service.network.model.packet.AbstractClientPacket;
import com.l2jserver.util.BufferUtils;
/**
* This packet is sent by the client once the login server has authorized
* authentication into this server. A new {@link Lineage2Session} object will be
* set to the current connection and the character list is sent to the client.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class CM_AUTH_LOGIN extends AbstractClientPacket {
/**
* The packet OPCODE
*/
public static final int OPCODE = 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<L2Character> chars = characterDao.selectByAccount(accountId);
conn.write(SM_CHAR_LIST.fromL2Session(conn.getSession(),
chars.toArray(new L2Character[chars.size()])));
}
/**
* @return the loginName
*/
public String getLoginName() {
return loginName;
}
/**
* @return the playKey1
*/
public int getPlayKey1() {
return playKey1;
}
/**
* @return the playKey2
*/
public int getPlayKey2() {
return playKey2;
}
/**
* @return the loginKey1
*/
public int getLoginKey1() {
return loginKey1;
}
/**
* @return the loginKey2
*/
public int getLoginKey2() {
return loginKey2;
}
}

View File

@@ -0,0 +1,120 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.client;
import java.util.StringTokenizer;
import org.jboss.netty.buffer.ChannelBuffer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.inject.Inject;
import com.l2jserver.model.id.ObjectID;
import com.l2jserver.model.id.object.NPCID;
import com.l2jserver.model.id.object.provider.ObjectIDResolver;
import com.l2jserver.model.world.NPC;
import com.l2jserver.model.world.npc.NPCController.NPCControllerException;
import com.l2jserver.service.game.character.CannotSetTargetServiceException;
import com.l2jserver.service.game.npc.ActionServiceException;
import com.l2jserver.service.game.npc.NPCService;
import com.l2jserver.service.network.model.Lineage2Client;
import com.l2jserver.service.network.model.packet.AbstractClientPacket;
import com.l2jserver.util.ArrayUtils;
import com.l2jserver.util.BufferUtils;
/**
* Executes an bypass command
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class CM_BYPASS extends AbstractClientPacket {
/**
* The logger
*/
private final Logger log = LoggerFactory.getLogger(this.getClass());
/**
* The packet OPCODE
*/
public static final int OPCODE = 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<NPC> 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;
}
}
}

View File

@@ -0,0 +1,142 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.client;
import org.jboss.netty.buffer.ChannelBuffer;
import com.google.inject.Inject;
import com.l2jserver.model.id.ObjectID;
import com.l2jserver.model.id.object.ItemID;
import com.l2jserver.model.id.object.NPCID;
import com.l2jserver.model.id.object.provider.ObjectIDResolver;
import com.l2jserver.model.world.Item;
import com.l2jserver.model.world.NPC;
import com.l2jserver.model.world.npc.NPCController.NPCControllerException;
import com.l2jserver.service.game.character.CannotSetTargetServiceException;
import com.l2jserver.service.game.character.CharacterAction;
import com.l2jserver.service.game.item.ItemNotOnGroundServiceException;
import com.l2jserver.service.game.item.ItemService;
import com.l2jserver.service.game.npc.ActionServiceException;
import com.l2jserver.service.game.npc.NPCService;
import com.l2jserver.service.game.spawn.NotSpawnedServiceException;
import com.l2jserver.service.network.model.Lineage2Client;
import com.l2jserver.service.network.model.SystemMessage;
import com.l2jserver.service.network.model.packet.AbstractClientPacket;
import com.l2jserver.util.geometry.Coordinate;
/**
* Executes an action from an character to an NPC
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class CM_CHAR_ACTION extends AbstractClientPacket {
/**
* The packet OPCODE
*/
public static final int OPCODE = 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;
}
}
}

View File

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

View File

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

View File

@@ -0,0 +1,105 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.client;
import org.jboss.netty.buffer.ChannelBuffer;
import com.google.inject.Inject;
import com.l2jserver.game.net.packet.server.SM_ACTION_FAILED;
import com.l2jserver.service.game.chat.CannotChatToSelfChatServiceException;
import com.l2jserver.service.game.chat.ChatBanActiveChatServiceException;
import com.l2jserver.service.game.chat.ChatMessageType;
import com.l2jserver.service.game.chat.ChatService;
import com.l2jserver.service.game.chat.ChatTargetOfflineServiceException;
import com.l2jserver.service.game.chat.TargetNotFoundChatServiceException;
import com.l2jserver.service.network.model.Lineage2Client;
import com.l2jserver.service.network.model.SystemMessage;
import com.l2jserver.service.network.model.packet.AbstractClientPacket;
import com.l2jserver.util.BufferUtils;
/**
* Completes the creation of an character. Creates the object, inserts into the
* database and notifies the client about the status of the operation.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class CM_CHAR_CHAT extends AbstractClientPacket {
/**
* The packet OPCODE
*/
public static final int OPCODE = 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);
}
}
}

View File

@@ -0,0 +1,190 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.client;
import 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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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());
}
}
}

View File

@@ -0,0 +1,150 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.client;
import org.jboss.netty.buffer.ChannelBuffer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.inject.Inject;
import com.l2jserver.game.net.packet.server.SM_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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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 <code>id</code>
*/
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);
}
}

View File

@@ -0,0 +1,44 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.client;
import org.jboss.netty.buffer.ChannelBuffer;
import com.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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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));
}
}

View File

@@ -0,0 +1,74 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.client;
import org.jboss.netty.buffer.ChannelBuffer;
import com.google.inject.Inject;
import com.l2jserver.service.game.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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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);
}
}

View File

@@ -0,0 +1,46 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.client;
import org.jboss.netty.buffer.ChannelBuffer;
import com.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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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()));
}
}

View File

@@ -0,0 +1,77 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.client;
import java.util.List;
import org.jboss.netty.buffer.ChannelBuffer;
import com.google.inject.Inject;
import com.l2jserver.game.net.packet.server.SM_CHAR_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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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<L2Character> 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)));
}
}

View File

@@ -0,0 +1,125 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.client;
import org.jboss.netty.buffer.ChannelBuffer;
import com.google.inject.Inject;
import com.l2jserver.model.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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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();
}
}
}

View File

@@ -0,0 +1,77 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.client;
import org.jboss.netty.buffer.ChannelBuffer;
import com.google.inject.Inject;
import com.l2jserver.service.game.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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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();
}
}
}

View File

@@ -0,0 +1,72 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.client;
import org.jboss.netty.buffer.ChannelBuffer;
import com.google.inject.Inject;
import com.l2jserver.service.game.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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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);
}
}
}

View File

@@ -0,0 +1,96 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.client;
import org.jboss.netty.buffer.ChannelBuffer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.inject.Inject;
import com.l2jserver.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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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
}
}
}

View File

@@ -0,0 +1,48 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.client;
import org.jboss.netty.buffer.ChannelBuffer;
import com.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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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());
}
}

View File

@@ -0,0 +1,47 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.client;
import org.jboss.netty.buffer.ChannelBuffer;
import com.l2jserver.service.network.model.Lineage2Client;
import com.l2jserver.service.network.model.packet.AbstractClientPacket;
/**
* The client is requesting a the key mappings.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
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
}
}

View File

@@ -0,0 +1,49 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.client;
import org.jboss.netty.buffer.ChannelBuffer;
import com.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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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"));
}
}

View File

@@ -0,0 +1,86 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.client;
import org.jboss.netty.buffer.ChannelBuffer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.inject.Inject;
import com.l2jserver.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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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;
}
}
}

View File

@@ -0,0 +1,71 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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<L2Character> chars = characterDao.selectByAccount(conn
.getSession().getAccountID());
conn.write(SM_CHAR_LIST.fromL2Session(conn.getSession(),
chars.toArray(new L2Character[chars.size()])));
}
}

View File

@@ -0,0 +1,105 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.client;
import org.jboss.netty.buffer.ChannelBuffer;
import com.google.inject.Inject;
import com.l2jserver.model.id.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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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);
}
}
}

View File

@@ -0,0 +1,127 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.client;
import org.jboss.netty.buffer.ChannelBuffer;
import com.google.inject.Inject;
import com.l2jserver.model.id.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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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();
}
}
}

View File

@@ -0,0 +1,52 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.client;
import org.jboss.netty.buffer.ChannelBuffer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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();
}
}

View File

@@ -0,0 +1,125 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.client;
import org.jboss.netty.buffer.ChannelBuffer;
import org.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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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);
}
});
}
}

View File

@@ -0,0 +1,92 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.client;
import org.jboss.netty.buffer.ChannelBuffer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.inject.Inject;
import com.l2jserver.game.net.packet.server.SM_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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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));
}
}

View File

@@ -0,0 +1,80 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.client;
import org.jboss.netty.buffer.ChannelBuffer;
import com.google.inject.Inject;
import com.l2jserver.game.net.packet.server.SM_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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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())));
}
}

View File

@@ -0,0 +1,50 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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) {
}
}

View File

@@ -0,0 +1,114 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.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 <a href="http://www.rogiel.com">Rogiel</a>
* @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<AttackHit> 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;
}
}

View File

@@ -0,0 +1,103 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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);
}
}
}

View File

@@ -0,0 +1,62 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.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 <a href="http://www.rogiel.com">Rogiel</a>
* @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
}
}

View File

@@ -0,0 +1,73 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.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 <a href="http://www.rogiel.com">Rogiel</a> 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());
}
}

View File

@@ -0,0 +1,59 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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());
}
}

View File

@@ -0,0 +1,219 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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<Stat, Integer> 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<Stat, Integer> 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;
}
}

View File

@@ -0,0 +1,116 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.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 <a href="http://www.rogiel.com">Rogiel</a>
* @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 <a href="http://www.rogiel.com">Rogiel</a>
*/
public enum Reason {
/**
* "Your character creation has failed."
*/
REASON_CREATION_FAILED(0x00),
/**
* "You cannot create another character. Please delete the existing
* character and try again." Removes all settings that were selected
* (race, class, etc)"
*/
REASON_TOO_MANY_CHARACTERS(0x01),
/**
* "This name already exists."
*/
REASON_NAME_ALREADY_EXISTS(0x02),
/**
* "Your title cannot exceed 16 characters in length. Please try again."
*/
REASON_16_ENG_CHARS(0x03),
/**
* "Incorrect name. Please try again."
*/
REASON_INCORRECT_NAME(0x04),
/**
* "Characters cannot be created from this server."
*/
REASON_CREATE_NOT_ALLOWED(0x05),
/**
* "Unable to create character. You are unable to create a new character
* on the selected server. A restriction is in place which restricts
* users from creating characters on different servers where no previous
* character exists. Please choose another server."
*/
REASON_CHOOSE_ANOTHER_SVR(0x06);
/**
* 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);
}
}

View File

@@ -0,0 +1,51 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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);
}
}

View File

@@ -0,0 +1,104 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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);
}
}

View File

@@ -0,0 +1,376 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.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
*
* <pre>
* (c) dddddSddddQdddddddddddddddddddddddddddddddddddddddddddddddddd
* ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd
* fdfdfdfddddSdddddcccddh[h]cdcdhhdhddddccdcccddddcdddddhhhhhhhdddd
* d
* </pre>
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
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);
}
}

View File

@@ -0,0 +1,293 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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);
}
}

View File

@@ -0,0 +1,60 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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
}
}

View File

@@ -0,0 +1,80 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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
}
}
}

View File

@@ -0,0 +1,226 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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<Item, InventoryUpdateType> items = CollectionFactory
.newMap();
/**
* The type of operation to be performed.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
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} <code>type</code> 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<Item, InventoryUpdateType> 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;
}
}

View File

@@ -0,0 +1,241 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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<L2Character> 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);
}
}

View File

@@ -0,0 +1,56 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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
}
}

View File

@@ -0,0 +1,54 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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
}
}

View File

@@ -0,0 +1,68 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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)
}
}

View File

@@ -0,0 +1,109 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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);
}
}

View File

@@ -0,0 +1,71 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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
}
}
}
}

View File

@@ -0,0 +1,69 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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
}
}

View File

@@ -0,0 +1,58 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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());
}
}

View File

@@ -0,0 +1,71 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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);
}
}

View File

@@ -0,0 +1,59 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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); // ??
}
}

View File

@@ -0,0 +1,68 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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
}
}

View File

@@ -0,0 +1,76 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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);
}
}
}

View File

@@ -0,0 +1,76 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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);
}
}

View File

@@ -0,0 +1,57 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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
}
}

View File

@@ -0,0 +1,77 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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);
}
}
}

View File

@@ -0,0 +1,114 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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
}
}

View File

@@ -0,0 +1,65 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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
}
}

View File

@@ -0,0 +1,69 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.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 <a href="http://www.rogiel.com">Rogiel</a>
* @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 <code>item</code>
* @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());
}
}

View File

@@ -0,0 +1,134 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.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.
*
* <pre>
* (c) cbddcd
* </pre>
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
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 <tt>key</tt> 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 <tt>key</tt> 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;
}
}

View File

@@ -0,0 +1,64 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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);
}
}
}

View File

@@ -0,0 +1,124 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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
}
}

View File

@@ -0,0 +1,56 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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);
}
}

View File

@@ -0,0 +1,76 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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
}
}

View File

@@ -0,0 +1,377 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.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 <a href="http://www.rogiel.com">Rogiel</a>
*/
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<SystemMessagePacketParameter> params = CollectionFactory
.newList();
/**
* System message parameter IDs
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
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<br>
* 0-9 Castle names<br>
* 21-64 CH names<br>
* 81-89 Territory names<br>
* 101-121 Fortress names<br>
*
* @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;
}
}

View File

@@ -0,0 +1,204 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.service.network;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelFutureListener;
import org.jboss.netty.channel.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 <a href="http://www.rogiel.com">Rogiel</a>
*/
@Depends({ LoggingService.class, ThreadService.class,
BlowfishKeygenService.class, WorldService.class })
public class NettyNetworkService extends
AbstractConfigurableService<NetworkServiceConfiguration> implements
NetworkService {
/**
* The logger
*/
private final Logger log = LoggerFactory.getLogger(this.getClass());
/**
* The {@link ThreadService}
*/
private final ThreadService threadService;
/**
* The Google Guice {@link Injector}
*/
private final Injector injector;
/**
* Netty Boss {@link ThreadPool}
*/
private ThreadPool bossPool;
/**
* Netty Worker {@link ThreadPool}
*/
private ThreadPool workerPool;
/**
* The server bootstrap
*/
private ServerBootstrap server;
/**
* The server channel
*/
private ServerChannel channel;
/**
* The client list. This list all active clients in the server
*/
private Set<Lineage2Client> clients = CollectionFactory.newSet();
/**
* @param injector
* the {@link Guice} {@link Injector}
* @param threadService
* the {@link ThreadService}
*/
@Inject
public 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();
}
}

View File

@@ -0,0 +1,385 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.service.network.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 <a href="http://www.rogiel.com">Rogiel</a>
*/
@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<PositionableObject>(
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);
}
}

View File

@@ -0,0 +1,174 @@
/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* l2jserver2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.service.network.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 <a href="http://www.rogiel.com">Rogiel</a>
*/
@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<Lineage2Client, GGFuture> futures;
/**
* The {@link MessageDigest} for SHA-1.
* <p>
* <b>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<GameGuardResponse> 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 <a href="http://www.rogiel.com">Rogiel</a>
*/
private class GGFuture extends AbstractFuture<GameGuardResponse> implements
Future<GameGuardResponse> {
@Override
protected boolean set(GameGuardResponse value) {
// protected wrapper
return super.set(value);
}
}
}