1
0
mirror of https://github.com/Rogiel/l2jserver2 synced 2025-12-07 07:52:57 +00:00

Merge branch 'proposed/database-derby-old' into proposed/database-derby

Conflicts:
	pom.xml
	src/assembly/distribution-h2-bin.xml
	src/assembly/distribution-mysql5-bin.xml
This commit is contained in:
2011-10-05 23:48:39 -03:00
18945 changed files with 4646 additions and 434 deletions

View File

@@ -0,0 +1,54 @@
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
<id>derby-bin</id>
<formats>
<!-- <format>tar.gz</format> -->
<!-- <format>tar.bz2</format> -->
<format>zip</format>
</formats>
<baseDirectory></baseDirectory>
<fileSets>
<fileSet>
<directory>${project.basedir}</directory>
<outputDirectory>/</outputDirectory>
<includes>
<include>data/**</include>
</includes>
<excludes>
<exclude>.gitignore</exclude>
<exclude>data/cache/**</exclude>
<exclude>data/pathing.db</exclude>
<exclude>data/database.h2.*</exclude>
</excludes>
</fileSet>
<fileSet>
<directory>${project.basedir}/distribution/global</directory>
<outputDirectory>/</outputDirectory>
</fileSet>
<fileSet>
<directory>${project.basedir}/distribution/sql</directory>
<outputDirectory>/</outputDirectory>
</fileSet>
<fileSet>
<directory>${project.build.directory}</directory>
<outputDirectory>/</outputDirectory>
<includes>
<include>${project.artifactId}-${project.version}.jar</include>
</includes>
</fileSet>
</fileSets>
<dependencySets>
<dependencySet>
<outputDirectory>/libs</outputDirectory>
<useProjectArtifact>true</useProjectArtifact>
<unpack>false</unpack>
<scope>runtime</scope>
<excludes>
<exclude>mysql:*</exclude>
<exclude>com.h2database:*</exclude>
</excludes>
</dependencySet>
</dependencySets>
</assembly>

View File

@@ -0,0 +1,53 @@
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
<id>h2-bin</id>
<formats>
<!-- <format>tar.gz</format> -->
<!-- <format>tar.bz2</format> -->
<format>zip</format>
</formats>
<baseDirectory></baseDirectory>
<fileSets>
<fileSet>
<directory>${project.basedir}</directory>
<outputDirectory>/</outputDirectory>
<includes>
<include>data/**</include>
</includes>
<excludes>
<exclude>.gitignore</exclude>
<exclude>data/cache/**</exclude>
<exclude>data/pathing.db</exclude>
<exclude>data/database.h2.*</exclude>
</excludes>
</fileSet>
<fileSet>
<directory>${project.basedir}/distribution/global</directory>
<outputDirectory>/</outputDirectory>
</fileSet>
<fileSet>
<directory>${project.basedir}/distribution/sql</directory>
<outputDirectory>/</outputDirectory>
</fileSet>
<fileSet>
<directory>${project.build.directory}</directory>
<outputDirectory>/</outputDirectory>
<includes>
<include>${project.artifactId}-${project.version}.jar</include>
</includes>
</fileSet>
</fileSets>
<dependencySets>
<dependencySet>
<outputDirectory>/libs</outputDirectory>
<useProjectArtifact>true</useProjectArtifact>
<unpack>false</unpack>
<scope>runtime</scope>
<excludes>
<exclude>mysql:mysql-connector-java</exclude>
</excludes>
</dependencySet>
</dependencySets>
</assembly>

View File

@@ -0,0 +1,53 @@
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
<id>mysql5-bin</id>
<formats>
<!-- <format>tar.gz</format> -->
<!-- <format>tar.bz2</format> -->
<format>zip</format>
</formats>
<baseDirectory></baseDirectory>
<fileSets>
<fileSet>
<directory>${project.basedir}</directory>
<outputDirectory>/</outputDirectory>
<includes>
<include>data/**</include>
</includes>
<excludes>
<exclude>.gitignore</exclude>
<exclude>data/cache/**</exclude>
<exclude>data/pathing.db</exclude>
<exclude>data/database.h2.*</exclude>
</excludes>
</fileSet>
<fileSet>
<directory>${project.basedir}/distribution/global</directory>
<outputDirectory>/</outputDirectory>
</fileSet>
<fileSet>
<directory>${project.basedir}/distribution/sql</directory>
<outputDirectory>/</outputDirectory>
</fileSet>
<fileSet>
<directory>${project.build.directory}</directory>
<outputDirectory>/</outputDirectory>
<includes>
<include>${project.artifactId}-${project.version}.jar</include>
</includes>
</fileSet>
</fileSets>
<dependencySets>
<dependencySet>
<outputDirectory>/libs</outputDirectory>
<useProjectArtifact>true</useProjectArtifact>
<unpack>false</unpack>
<scope>runtime</scope>
<excludes>
<exclude>com.h2database:h2</exclude>
</excludes>
</dependencySet>
</dependencySets>
</assembly>

View File

@@ -0,0 +1,34 @@
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
<id>src</id>
<formats>
<!-- <format>tar.gz</format> -->
<!-- <format>tar.bz2</format> -->
<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,37 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver;
import com.google.inject.AbstractModule;
import com.google.inject.Module;
import com.l2jserver.model.id.provider.IDProviderModule;
import com.l2jserver.service.ServiceModule;
import com.l2jserver.service.database.MySQL5DAOModule;
/**
* The game server Google Guice {@link Module}.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class GameServerModule extends AbstractModule {
@Override
protected void configure() {
install(new ServiceModule());
install(new IDProviderModule());
install(new MySQL5DAOModule());
}
}

View File

@@ -0,0 +1,27 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver;
import com.l2jserver.service.configuration.Configuration;
/**
* General configuration interface
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public interface GeneralConfiguration extends Configuration {
}

View File

@@ -0,0 +1,33 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver;
import com.l2jserver.game.net.ProtocolVersion;
/**
* Constant values for this L2J compilation
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class L2JConstant {
/**
* Indicate the supported protocol for this compilation.
* <p>
* This <b>MUST</b> be hard-coded!
*/
public static final ProtocolVersion SUPPORTED_PROTOCOL = ProtocolVersion.FREYA;
}

View File

@@ -0,0 +1,42 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver;
import com.google.inject.Guice;
import com.google.inject.Injector;
/**
* The L2JGameServer class
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class L2JGameServer {
/**
* The server injector
*/
private final Injector injector = Guice
.createInjector(new GameServerModule());
/**
* Get the injector
*
* @return the injector
*/
public Injector getInjector() {
return injector;
}
}

View File

@@ -0,0 +1,119 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver;
import com.l2jserver.service.ServiceManager;
import com.l2jserver.service.cache.CacheService;
import com.l2jserver.service.configuration.ConfigurationService;
import com.l2jserver.service.database.DatabaseService;
import com.l2jserver.service.game.character.CharacterService;
import com.l2jserver.service.game.chat.ChatService;
import com.l2jserver.service.game.map.pathing.PathingService;
import com.l2jserver.service.game.npc.NPCService;
import com.l2jserver.service.game.scripting.ScriptingService;
import com.l2jserver.service.game.template.TemplateService;
import com.l2jserver.service.game.world.WorldIDService;
import com.l2jserver.service.network.NetworkService;
import com.l2jserver.service.network.keygen.BlowfishKeygenService;
/**
* Main class
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class L2JGameServerMain {
/**
* Main method
*
* @param args
* no arguments are used
*/
public static void main(String[] args) {
final L2JGameServer server = new L2JGameServer();
try {
final ServiceManager serviceManager = server.getInjector()
.getInstance(ServiceManager.class);
serviceManager.start(CacheService.class);
serviceManager.start(ConfigurationService.class);
serviceManager.start(DatabaseService.class);
serviceManager.start(WorldIDService.class);
serviceManager.start(ScriptingService.class);
serviceManager.start(TemplateService.class);
serviceManager.start(ChatService.class);
serviceManager.start(NPCService.class);
serviceManager.start(CharacterService.class);
serviceManager.start(PathingService.class);
serviceManager.start(BlowfishKeygenService.class);
serviceManager.start(NetworkService.class);
// final long free = Runtime.getRuntime().freeMemory();
// final long allocated = Runtime.getRuntime().totalMemory();
// final long maximum = Runtime.getRuntime().maxMemory();
// final long processors =
// Runtime.getRuntime().availableProcessors();
} catch (Exception e) {
System.out.println("GameServer could not be started!");
e.printStackTrace();
System.exit(0);
}
}
//
// /**
// * This method does an static spawn for an object
// *
// * @throws AlreadySpawnedServiceException
// * @throws SpawnPointNotFoundServiceException
// */
// private static void staticSpawn(Injector injector)
// throws SpawnPointNotFoundServiceException,
// AlreadySpawnedServiceException {
// final NPCTemplateIDProvider templateProvider = injector
// .getInstance(NPCTemplateIDProvider.class);
// final NPCIDProvider provider = injector
// .getInstance(NPCIDProvider.class);
// final SpawnService spawnService = injector
// .getInstance(SpawnService.class);
//
// final NPCTemplateID id = templateProvider.createID(12077);
// final NPC npc = id.getTemplate().create();
//
// npc.setID(provider.createID());
// // close to char spawn
// npc.setPoint(Point.fromXYZ(-71301, 258259, -3134));
//
// spawnService.spawn(npc, null);
//
// // close spawn gatekepper
// final NPCTemplateID gid = templateProvider.createID(30006);
// final NPC gatekeeper = gid.getTemplate().create();
// gatekeeper.setID(provider.createID());
// gatekeeper.setPoint(Point.fromXYZ(-71301, 258559, -3134));
// spawnService.spawn(gatekeeper, null);
//
// // spawn tamil - orc village
// final NPCTemplateID tamilId = templateProvider.createID(30576);
// final NPC tamil = tamilId.getTemplate().create();
// tamil.setID(provider.createID());
// tamil.setPoint(Point.fromXYZ(-45264, -112512, -240));
// spawnService.spawn(tamil, null);
// }
}

View File

@@ -0,0 +1,72 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.ai;
import com.google.inject.Inject;
import com.l2jserver.game.ai.desires.Desire;
import com.l2jserver.game.ai.desires.DesireQueue;
import com.l2jserver.model.world.Actor;
import com.l2jserver.service.game.world.WorldService;
import com.l2jserver.service.game.world.event.WorldEventDispatcher;
/**
* @author <a href="http://www.rogiel.com">Rogiel</a>
* @param <T>
* the {@link Actor} type for this {@link AI}
*/
public abstract class AI<T extends Actor> {
/**
* The desire queue for this AI
*/
protected DesireQueue desireQueue = new DesireQueue();
/**
* The actor controlled by this AI
*/
protected final T actor;
/**
* The {@link WorldService} event dispatcher
*/
@Inject
protected WorldEventDispatcher eventDispatcher;
/**
* Creates a new AI
*
* @param actor
* the actor controlled by this {@link AI}
*/
protected AI(T actor) {
this.actor = actor;
}
/**
* Executes an AI tick
*/
protected void tick() {
Desire desire = desireQueue.poll();
handleDesire(desire);
}
/**
* Handles the given desire
*
* @param desire
* the desire
*/
protected abstract void handleDesire(Desire desire);
}

View File

@@ -0,0 +1,73 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.ai.desires;
/**
* This class implements basic functionality common for each desire
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
* @see com.l2jserver.game.ai.desires.Desire
* @see com.l2jserver.game.ai.desires.DesireQueue
* @see com.l2jserver.game.ai.AI
* @see com.l2jserver.game.ai.AI#handleDesire(Desire)
*/
public abstract class AbstractDesire implements Desire {
/**
* Desire power. It's used to calculate what npc whants to do most of all.
*/
protected int desirePower;
/**
* Creates new desire. By design any desire should have desire power. So
* constructor accepts basic amout.
*
* @param desirePower
* basic amount of desirePower
*/
protected AbstractDesire(int desirePower) {
this.desirePower = desirePower;
}
/**
* Compares this desire with another, used by
* {@link com.l2jserver.game.ai.desires.DesireQueue} to keep track of desire
* priorities.
*
* @param o
* desire to compare with
* @return result of desire comparation
*/
@Override
public int compareTo(Desire o) {
return o.getDesirePower() - getDesirePower();
}
@Override
public synchronized int getDesirePower() {
return desirePower;
}
@Override
public synchronized void increaseDesirePower(int desirePower) {
this.desirePower = this.desirePower + desirePower;
}
@Override
public synchronized void reduceDesirePower(int desirePower) {
this.desirePower = this.desirePower - desirePower;
}
}

View File

@@ -0,0 +1,70 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.ai.desires;
import com.l2jserver.model.world.Actor;
/**
* This class indicates that character wants to attack somebody
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public final class AttackDesire extends AbstractDesire {
/**
* Target of this desire
*/
protected final Actor target;
/**
* Creates new attack desire, target can't be changed
*
* @param target
* whom to attack
* @param desirePower
* initial attack power
*/
protected AttackDesire(Actor target, int desirePower) {
super(desirePower);
this.target = target;
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (!(o instanceof AttackDesire))
return false;
AttackDesire that = (AttackDesire) o;
return target.equals(that.target);
}
@Override
public int hashCode() {
return target.hashCode();
}
/**
* Returns target of this desire
*
* @return target of this desire
*/
public Actor getTarget() {
return target;
}
}

View File

@@ -0,0 +1,80 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.ai.desires;
/**
* This interface represents basic desire functions.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
* @see com.l2jserver.game.ai.AI
* @see com.l2jserver.game.ai.AI#handleDesire(Desire)
* @see com.l2jserver.game.ai.desires.AbstractDesire
*/
public interface Desire extends Comparable<Desire> {
/**
* Returns hashcode for this object, must be overrided by child
*
* @return hashcode for this object
*/
@Override
int hashCode();
/**
* Compares this Desire with another object, must overriden by child
*
* @param obj
* another object to compare with
* @return result of object comparation
*/
@Override
boolean equals(Object obj);
/**
* Returns desire power of this object
*
* @return desire power of the object
*/
int getDesirePower();
/**
* Adds desire power to this desire, this call is synchronized.<br>
* <br>
* <b>WARNING!!! Changing desire power after adding it to queue will not
* affect it's position, you have to call
* {@link com.l2jserver.game.ai.desires.DesireQueue#addDesire(Desire)}
* passing this instance as argument</b>
*
* @param desirePower
* amount of desirePower to add
* @see DesireQueue#addDesire(Desire)
*/
void increaseDesirePower(int desirePower);
/**
* Reduces desire power by give amount.<br>
* <br>
* <b>WARNING!!! Changing desire power after adding it to queue will not
* affect it's position, you have to call
* {@link com.l2jserver.game.ai.desires.DesireQueue#addDesire(Desire)}
* passing this instance as argument</b>
*
* @param desirePower
* amount of desirePower to substract
* @see DesireQueue#addDesire(Desire)
*/
void reduceDesirePower(int desirePower);
}

View File

@@ -0,0 +1,46 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.ai.desires;
/**
* This class represents simple filter for desire iterations.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public interface DesireIteratorFilter {
/**
* This method is called each time for every desire that is in the queue.<br>
* <br>
* {@link java.util.ConcurrentModificationException} will be thrown by
* {@link com.l2jserver.game.ai.desires.DesireQueue#iterateDesires(DesireIteratorHandler, DesireIteratorFilter[])}
* if any of the following methods will be called from here:
* <ul>
* <li>{@link com.l2jserver.game.ai.desires.DesireQueue#addDesire(Desire)}</li>
* <li>{@link com.l2jserver.game.ai.desires.DesireQueue#poll()}</li>
* <li>
* {@link com.l2jserver.game.ai.desires.DesireQueue#removeDesire(Desire)}</li>
* </ul>
* <p/>
* However {@link com.l2jserver.game.ai.desires.DesireQueue#clear()} can be
* called.
*
* @param desire
* current element of iteration that is beeing filtered
* @return true if this filter accepted desire, false otherwise
*/
public boolean isOk(Desire desire);
}

View File

@@ -0,0 +1,56 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.ai.desires;
import java.util.Iterator;
/**
* This class is designed to be a helper class for desires.<br>
* Direct access to desire list is not allowed, however this interface can be
* used for iteration.<br>
* <br>
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
* @see com.l2jserver.game.ai.desires.DesireIteratorFilter
* @see com.l2jserver.game.ai.desires.DesireQueue#iterateDesires(DesireIteratorHandler,
* DesireIteratorFilter[])
*/
public interface DesireIteratorHandler {
/**
* This method is called each time for every desire that is in the queue.<br>
* Remove of desire must be handeled by <b>iterator.remove();</b><br>
* <br>
* {@link java.util.ConcurrentModificationException} will be thrown by
* {@link com.l2jserver.game.ai.desires.DesireQueue#iterateDesires(DesireIteratorHandler, DesireIteratorFilter[])}
* if any of the following methods will be called from here:
* <ul>
* <li>{@link com.l2jserver.game.ai.desires.DesireQueue#addDesire(Desire)}</li>
* <li>{@link com.l2jserver.game.ai.desires.DesireQueue#poll()}</li>
* <li>
* {@link com.l2jserver.game.ai.desires.DesireQueue#removeDesire(Desire)}</li>
* </ul>
* <p/>
* However {@link com.l2jserver.game.ai.desires.DesireQueue#clear()} can be
* called.
*
* @param desire
* current element of iteration
* @param iterator
* iterator object
*/
public void next(Desire desire, Iterator<Desire> iterator);
}

View File

@@ -0,0 +1,212 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.ai.desires;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.PriorityQueue;
/**
* This class represents desire queue, it's thread-safe. Desires can be added
* and removed. If desire is added - previous desires will be checked, if same
* desire found then desire previous one will be removed from the queue
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
* @see com.l2jserver.game.ai.desires.Desire
* @see com.l2jserver.game.ai.desires.AbstractDesire
*/
public class DesireQueue {
/**
* Prioritized Queue of desires, lazy initialization.
*/
protected PriorityQueue<Desire> queue;
/**
* Returns first element of this queue not removing it. Returns null if
* there is no elements.
*
* @return first element or null
*/
public synchronized Desire peek() {
return queue != null ? queue.peek() : null;
}
/**
* Removes first element from the desires list and removes it. Returns null
* if there are no elements.
*
* @return first element from the desires list or null.
*/
public synchronized Desire poll() {
if (queue != null) {
return queue.poll();
}
return null;
}
/**
* Adds desire to the queue.
* <p/>
* <p/>
* When adding object this method checks first for the same object by
* {@link AbstractDesire#equals(Object)}, if such object found, next actions
* will be done:<br>
* <br>
* 1). Remove old desire instance from the list.<br>
* 2). Check if those desires are same instances by "==".<br>
* 3). If they are not the same instances, add desire power from old
* instance to new instance, if they are - do nothing.<br>
* <br>
* After all add new desire instance to the list.
*
* @param desire
* desire instance to add
*/
public synchronized void addDesire(Desire desire) {
// Lazy initialization of desire queue
if (queue == null) {
queue = new PriorityQueue<Desire>();
}
// Iterate over the list to find similar desires
Iterator<Desire> iterator = queue.iterator();
while (iterator.hasNext()) {
Desire iterated = iterator.next();
// Find similar desires by #equals method, they can be different
// instances.
if (desire.equals(iterated)) {
// Remove the old desire from the list
iterator.remove();
// If current desire instance was not at the list - increase
// it's power by the value of another instance power
// and after that add it to the list
if (desire != iterated) {
desire.increaseDesirePower(iterated.getDesirePower());
}
// Break iteration, desire list can't contain two same desires
break;
}
}
// finally add desire to the list
queue.add(desire);
}
/**
* Removes desire from this desireQueue. If desire was removed successfully
* this method return true, false otherwise
*
* @param desire
* what desire to remove
* @return result of desire removal
*/
public synchronized boolean removeDesire(Desire desire) {
return queue != null && queue.remove(desire);
}
/**
* Iterates over desires, you have to provide iteration handler and
* optionally filters.<br>
* <br>
* Handlers and filters can't call following methods:
* <ul>
* <li>{@link #addDesire(Desire)}</li>
* <li>{@link #poll()}</li>
* <li>{@link #removeDesire(Desire)}</li>
* </ul>
* <p/>
* However, method {@link #clear() can be called}.
*
* @param handler
* DesireIterationhandler that will be called on the iteration
* @param filters
* optional filters that will prevent passing unneeded desires to
* the handler
* @throws java.util.ConcurrentModificationException
* only if called handler or filter modified this queue
* @see com.l2jserver.game.ai.desires.DesireIteratorFilter
* @see com.l2jserver.game.ai.desires.DesireIteratorFilter#isOk(Desire)
* @see com.l2jserver.game.ai.desires.DesireIteratorHandler
* @see com.l2jserver.game.ai.desires.DesireIteratorHandler#next(Desire ,
* java.util.Iterator)
*/
public synchronized void iterateDesires(DesireIteratorHandler handler,
DesireIteratorFilter... filters)
throws ConcurrentModificationException {
if (queue == null) {
return;
}
Iterator<Desire> iterator = queue.iterator();
outer: while (iterator.hasNext()) {
Desire desire = iterator.next();
if (filters != null && filters.length > 0) {
for (DesireIteratorFilter filter : filters) {
if (!filter.isOk(desire)) {
continue outer;
}
}
}
handler.next(desire, iterator);
}
}
/**
* Returns true if this desire list contains same desire. Desires are
* compared by {@link AbstractDesire#equals(Object)} method.
*
* @param desire
* what desire to search
* @return true if there is equal desire, false in other case.
*/
public synchronized boolean contains(Desire desire) {
return queue.contains(desire);
}
/**
* Returns true if this NPC has no any desires added
*
* @return true if this NPC has no any desires added
*/
public synchronized boolean isEmpty() {
return queue == null || queue.isEmpty();
}
/**
* Clears all desires
*/
public synchronized void clear() {
if (queue != null) {
queue.clear();
}
}
/**
* Returns size of the desire list
*
* @return size of remaining desires
*/
public synchronized int size() {
return queue == null ? 0 : queue.size();
}
}

View File

@@ -0,0 +1,71 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.ai.desires;
import com.l2jserver.model.world.Actor;
import com.l2jserver.util.geometry.Point3D;
/**
* This class indicates that {@link Actor} wants to move somewhere
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public final class MoveDesire extends AbstractDesire {
/**
* Target of this desire
*/
protected final Point3D point;
/**
* Creates new move desire. Target can't be changed
*
* @param point
* where to move
* @param desirePower
* initial attack power
*/
protected MoveDesire(Point3D point, int desirePower) {
super(desirePower);
this.point = point;
}
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (!(o instanceof MoveDesire))
return false;
MoveDesire that = (MoveDesire) o;
return point.equals(that.point);
}
@Override
public int hashCode() {
return point.hashCode();
}
/**
* Returns target of this desire
*
* @return target of this desire
*/
public Point3D getTarget() {
return point;
}
}

View File

@@ -0,0 +1,399 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net;
import java.util.Set;
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.ServerPacket;
import com.l2jserver.game.net.packet.server.SM_ACTION_FAILED;
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.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.game.world.WorldService;
import com.l2jserver.service.game.world.filter.impl.CharacterBroadcastFilter;
import com.l2jserver.service.network.NetworkService;
import com.l2jserver.util.factory.CollectionFactory;
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} and {@link #broadcast(ServerPacket) broadcasting} packets.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class 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;
// services
/**
* The {@link NetworkService} instance. This service is used to retrieve the
* {@link Lineage2Client} based on an {@link CharacterID}.
*/
private final NetworkService networkService;
/**
* The {@link WorldService} instance. This service is used to dynamically
* generate knownlists.
*/
private final WorldService worldService;
/**
* Creates a new instance
*
* @param worldService
* the world service
* @param networkService
* the network service
* @param channel
* the channel
*/
public Lineage2Client(WorldService worldService,
NetworkService networkService, Channel channel) {
this.worldService = worldService;
this.networkService = networkService;
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 com.l2jserver.game.net.ProtocolVersion#supports(com.l2jserver.game.net.ProtocolVersion)
*/
public boolean supports(ProtocolVersion version) {
if (version == null)
return false;
return 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(message.packet);
}
/**
* 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);
}
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));
}
/**
* Broadcast a packet to all characters in this character knownlist.
* <p>
* Note that in the broadcasting process, this client will be included.
* <p>
* Please note that this method will <b>not</b> block for all packets to be
* sent. It is possible to check if all packets were sent successfully using
* the {@link ChannelFuture} instances.
*
* @param packet
* the packet
* @return an {@link Set} containing all {@link ChannelFuture} instances.
*/
public Set<ChannelFuture> broadcast(ServerPacket packet) {
final Set<ChannelFuture> futures = CollectionFactory.newSet();
for (final L2Character character : worldService
.iterable(new CharacterBroadcastFilter(characterID.getObject()))) {
final Lineage2Client conn = networkService.discover(character
.getID());
if (conn == null)
continue;
futures.add(conn.write(packet));
}
return futures;
}
/**
* 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);
}
}

View File

@@ -0,0 +1,89 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net;
import java.util.Arrays;
/**
* Manages the cryptography key used to write/read packets. This class also
* updates the key once data has been sent/received.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class Lineage2CryptographyKey {
/**
* The raw key
*/
public final byte[] key;
/**
* Creates a new instance
*
* @param key
* the raw key
*/
public Lineage2CryptographyKey(byte[] key) {
this.key = key;
}
/**
* @return the key
*/
public byte[] getKey() {
return key;
}
/**
* Get the key value for byte index <tt>i</tt>
*
* @param i
* the index i
* @return the key byte
*/
public byte get(int i) {
return key[i & 15];
}
/**
* Updates this key once data has been sent/received.
*
* @param size
* the data size
*/
public void update(int size) {
int old = key[8] & 0xff;
old |= key[9] << 8 & 0xff00;
old |= key[10] << 0x10 & 0xff0000;
old |= key[11] << 0x18 & 0xff000000;
old += size;
key[8] = (byte) (old & 0xff);
key[9] = (byte) (old >> 0x08 & 0xff);
key[10] = (byte) (old >> 0x10 & 0xff);
key[11] = (byte) (old >> 0x18 & 0xff);
}
/**
* Creates a copy of this key
*
* @return the copied key
*/
public Lineage2CryptographyKey copy() {
return new Lineage2CryptographyKey(Arrays.copyOf(key, key.length));
}
}

View File

@@ -0,0 +1,103 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. 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.service.game.world.WorldService;
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;
/**
* The {@link WorldService} instance
*/
private final WorldService worldService;
/**
* Creates a new instance of this pipeline
*
* @param injector
* the {@link Guice} {@link Injector}
* @param networkService
* the network service
* @param worldService
* the world service
*/
@Inject
public Lineage2PipelineFactory(Injector injector,
NetworkService networkService, WorldService worldService) {
this.injector = injector;
this.nettyNetworkService = (NettyNetworkService) networkService;
this.worldService = worldService;
}
@Override
public ChannelPipeline getPipeline() throws Exception {
final ChannelPipeline pipeline = pipeline();
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));
pipeline.addLast("packet.handler", new Lineage2PacketHandler(
nettyNetworkService, worldService));
return pipeline;
}
}

View File

@@ -0,0 +1,107 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net;
import com.l2jserver.model.id.AccountID;
/**
* Lineage 2 session with the username and loginserver keys
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class Lineage2Session {
/**
* The account ID
*/
private final AccountID accountID;
/**
* The play key, part 1
*/
private final int playKey1;
/**
* The play key, part 2
*/
private final int playKey2;
/**
* The login key, part 1
*/
private final int loginKey1;
/**
* The login key, part 2
*/
private final int loginKey2;
/**
* Creates a new instance
*
* @param accountID
* the account ID
* @param playOK1
* the play key, part 1
* @param playOK2
* the play key, part 2
* @param loginOK1
* the login key, part 1
* @param loginOK2
* the login key, part 2
*/
public Lineage2Session(AccountID accountID, int playOK1, int playOK2,
int loginOK1, int loginOK2) {
this.accountID = accountID;
this.playKey1 = playOK1;
this.playKey2 = playOK2;
this.loginKey1 = loginOK1;
this.loginKey2 = loginOK2;
}
/**
* @return the account ID
*/
public AccountID getAccountID() {
return accountID;
}
/**
* @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,102 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net;
/**
* Represents the protocol version used by the client
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public enum ProtocolVersion {
/**
* The Release version, this is acctually a pseudo version. It never really
* existed.
*/
RELEASE(0),
/**
* The Interlude(200) version
*/
INTERLUDE(200, RELEASE),
/**
* The Freya(216) version
*/
FREYA(216, RELEASE),
/**
* The High5(268) version
*/
HIGH5(268, FREYA);
/**
* The parent version
*/
public final ProtocolVersion parent;
/**
* This version numeric ID
*/
public final int version;
/**
* Creates a new instance
*
* @param version
* the version integer id
*/
ProtocolVersion(int version) {
this(version, null);
}
/**
* Creates a new instance with a parent version
*
* @param version
* the version integer id
* @param parent
* the parent version
*/
ProtocolVersion(int version, ProtocolVersion parent) {
this.version = version;
this.parent = parent;
}
/**
* Checks if an given version is compatible with this
*
* @param version
* the target version to be tested
* @return true if version is compatible
*/
public boolean supports(ProtocolVersion version) {
if (this == version)
return true;
if (this.parent == null)
return false;
return this.parent.supports(version);
}
/**
* @param version
* the version integer id
* @return the detected version from the numeric id. Can be <tt>null</tt>
*/
public static ProtocolVersion fromVersion(int version) {
for (ProtocolVersion v : values()) {
if (v.version == version)
return v;
}
return null;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,109 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. 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.game.net.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 l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. 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.game.net.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 l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. 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 l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. 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,211 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. 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.Lineage2Client;
import com.l2jserver.game.net.packet.ClientPacket;
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_ATTACK;
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_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_CHAT;
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_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;
/**
* 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_CHAT.OPCODE:
return CM_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_ATTACK.OPCODE:
return CM_ATTACK.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 l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. 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.game.net.Lineage2Client;
import com.l2jserver.game.net.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 l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. 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.Lineage2Client;
import com.l2jserver.game.net.packet.ClientPacket;
import com.l2jserver.service.game.world.WorldService;
import com.l2jserver.service.network.NettyNetworkService;
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 {@link WorldService} instance
*/
private final WorldService worldService;
/**
* The Lineage 2 connection
*/
private Lineage2Client connection;
/**
* Creates a new instance of the packet handler
*
* @param nettyNetworkService
* the netty network service
* @param worldService
* the world service
*/
public Lineage2PacketHandler(NettyNetworkService nettyNetworkService,
WorldService worldService) {
this.nettyNetworkService = nettyNetworkService;
this.worldService = worldService;
}
@Override
public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e)
throws Exception {
connection = new Lineage2Client(worldService, nettyNetworkService,
e.getChannel());
connection.getPacketWriter().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,26 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet;
/**
* An abstract {@link ClientPacket}
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
* @see ClientPacket
*/
public abstract class AbstractClientPacket implements ClientPacket {
}

View File

@@ -0,0 +1,45 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet;
/**
* An abstract {@link ServerPacket}
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
* @see ServerPacket
*/
public abstract class AbstractServerPacket implements ServerPacket {
/**
* The packet OPCODE
*/
private final int opcode;
/**
* Creates a new instance of the packet
*
* @param opcode
* the packet opcode
*/
public AbstractServerPacket(int opcode) {
this.opcode = opcode;
}
@Override
public int getOpcode() {
return opcode;
}
}

View File

@@ -0,0 +1,49 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet;
import org.jboss.netty.buffer.ChannelBuffer;
import com.l2jserver.game.net.Lineage2Client;
/**
* Each implementation is an packet sent by the game client.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public interface ClientPacket extends Packet {
/**
* Read binary data in the {@link ChannelBuffer}.
* <p>
* Please do not write packets from this method. If you need to close the
* connection or write packets do it in {@link #process(Lineage2Client)}.
*
* @param client
* the active connection
* @param buffer
* the buffer
*/
void read(Lineage2Client client, ChannelBuffer buffer);
/**
* Process the packet. Executes all needed operations.
*
* @param conn
* The active Lineage2Connection
*/
void process(Lineage2Client conn);
}

View File

@@ -0,0 +1,33 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet;
import com.google.inject.AbstractModule;
import com.google.inject.Module;
import com.l2jserver.game.net.packet.client.CM_PROTOCOL_VERSION;
/**
* Google Guice {@link Module} for client packets
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class ClientPacketModule extends AbstractModule {
@Override
protected void configure() {
bind(CM_PROTOCOL_VERSION.class);
}
}

View File

@@ -0,0 +1,26 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet;
/**
* An simple packet. This must not be used directly, use {@link ClientPacket} or
* {@link ServerPacket} instead.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public interface Packet {
}

View File

@@ -0,0 +1,33 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet;
import com.google.inject.AbstractModule;
import com.google.inject.Module;
/**
* Google Guice {@link Module} for packets
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class PacketModule extends AbstractModule {
@Override
protected void configure() {
install(new ClientPacketModule());
install(new ServerPacketModule());
}
}

View File

@@ -0,0 +1,48 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet;
import org.jboss.netty.buffer.ChannelBuffer;
import com.l2jserver.game.net.Lineage2Client;
/**
* Each implementation is an packet sent by the game server.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public interface ServerPacket extends Packet {
/**
* Writes this packet binary data.
* <p>
* Please do not write packets from this method! This is only used to test
* compatibility of protocols.
*
* @param client
* the connection
* @param buffer
* the buffer
*/
void write(Lineage2Client client, ChannelBuffer buffer);
/**
* Get the opcode id of this packet
*
* @return the opcode id
*/
int getOpcode();
}

View File

@@ -0,0 +1,33 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet;
import com.google.inject.AbstractModule;
import com.google.inject.Module;
import com.l2jserver.game.net.packet.client.CM_PROTOCOL_VERSION;
/**
* Google Guice {@link Module} for server packets
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class ServerPacketModule extends AbstractModule {
@Override
protected void configure() {
bind(CM_PROTOCOL_VERSION.class);
}
}

View File

@@ -0,0 +1,205 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. 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.Lineage2Client;
import com.l2jserver.game.net.packet.AbstractClientPacket;
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;
/**
* This packet notifies the server which character the player has chosen to use.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class CM_ACTION_USE extends AbstractClientPacket {
/**
* The packet OPCODE
*/
public static final int OPCODE = 0x56;
/**
* The {@link CharacterService}
*/
private final CharacterService charService;
/**
* The action to be performed
*/
private Action action;
/**
* The enumeration of all possible actions
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public enum Action {
/**
* Toggles the character in SIT or STAND mode
*/
SIT_STAND(0),
/**
* Toggles the character in WALK or RUN mode
*/
WALK_RUN(1),
/**
* Stats a new private store sell
*/
PRIVATE_STORE_SELL(10),
/**
* Stats a new private store buy
*/
PRIVATE_STORE_BUY(11),
/**
* Sets the pet in follow mode
*/
PET_FOLLOW_MOVE(15),
/**
* Sets the pet in follow mode 2
*/
PET_FOLLOW_MOVE2(21),
/**
* Orders the pet to attack
*/
PET_ATTACK(16),
/**
* Orders the pet to attack (second type)
*/
PET_ATTACK2(22),
/**
* Orders the pet to stop
*/
PET_STOP(17),
/**
* Orders the pet to stop (second type)
*/
PET_STOP2(23),
/**
* Unsummons the pet
*/
PET_UNSUMMON(19),
/**
* Mounts or dismount from pet
*/
MOUNT_DISMOUNT(38),
/**
* Switch Wild Hog Cannon mode
*/
WILD_HOG_CANNON_SWITCH_MODE(32),
/**
* Stops Wild Hog Cannon
*/
WILD_HOG_CANNON_STOP(41),
/**
* Souless toxic smoke
*/
SOULESS_TOXIC_SMOKE(36),
/**
* Souless parasite burst
*/
SOULESS_PARASITE_BURST(39),
/**
* Creates a new darwven manufacture
*/
DWARVEN_MANUFACTURE(37);
/**
* The numeric action id
*/
public final int id;
/**
* @param id
* the numeric action id
*/
Action(int id) {
this.id = id;
}
/**
* Resolves the numeric id into an Java type action
*
* @param id
* the numeric id
* @return the resolved action
*/
public static Action fromID(int id) {
for (final Action action : values())
if (action.id == id)
return action;
return null;
}
}
/**
* If CTRL key was pressed for this action
*/
@SuppressWarnings("unused")
private boolean ctrlPressed;
/**
* If SHIFT key was pressed for this action
*/
@SuppressWarnings("unused")
private boolean shiftPressed;
/**
* @param charService
* the character service
*/
@Inject
public CM_ACTION_USE(CharacterService charService) {
this.charService = charService;
}
@Override
public void read(Lineage2Client conn, ChannelBuffer buffer) {
action = Action.fromID(buffer.readInt());
ctrlPressed = (buffer.readByte() == 1 ? true : false);
shiftPressed = (buffer.readByte() == 1 ? true : false);
}
@Override
public void process(final Lineage2Client conn) {
final L2Character character = conn.getCharacter();
switch (action) {
case SIT_STAND:
// TODO
break;
case WALK_RUN:
try {
if (character.getMoveType() == CharacterMoveType.WALK) {
charService.run(character);
} else {
charService.walk(character);
}
} catch (CharacterAlreadyWalkingServiceException e) {
conn.sendActionFailed();
} catch (CharacterAlreadyRunningServiceException e) {
conn.sendActionFailed();
}
break;
}
}
}

View File

@@ -0,0 +1,84 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. 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.Lineage2Client;
import com.l2jserver.game.net.packet.AbstractClientPacket;
import com.l2jserver.service.game.admin.AdministratorService;
import com.l2jserver.util.BufferUtils;
/**
* Executes an administrator action
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class CM_ADMIN_COMMAND extends AbstractClientPacket {
/**
* The packet OPCODE
*/
public static final int OPCODE = 0x74;
/**
* The admin service
*/
private final AdministratorService adminService;
/**
* The command
*/
@SuppressWarnings("unused")
private String command;
/**
* @param adminService
* the administrator service
*/
@Inject
public CM_ADMIN_COMMAND(AdministratorService adminService) {
this.adminService = adminService;
}
@Override
public void read(Lineage2Client conn, ChannelBuffer buffer) {
command = BufferUtils.readString(buffer).trim();
}
@Override
public void process(final Lineage2Client conn) {
// final StringTokenizer tokenizer = new StringTokenizer(command, " ");
// final String cmd = tokenizer.nextToken();
// if (cmd.equals("tele")) {
// Coordinate coord = Coordinate.fromXYZ(
// Integer.parseInt(tokenizer.nextToken()),
// Integer.parseInt(tokenizer.nextToken()),
// Integer.parseInt(tokenizer.nextToken()));
// try {
// spawnService.teleport(conn.getCharacter(), coord);
// } catch (NotSpawnedServiceException e) {
// conn.sendActionFailed();
// } catch (CharacterAlreadyTeleportingServiceException e) {
// conn.sendActionFailed();
// }
// }
adminService.command(conn, conn.getCharacter(), "", new String[] {});
// TODO implement admin commands
}
}

View File

@@ -0,0 +1,165 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. 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.Lineage2Client;
import com.l2jserver.game.net.packet.AbstractClientPacket;
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.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_ATTACK extends AbstractClientPacket {
/**
* The packet OPCODE
*/
public static final int OPCODE = 0x01;
/**
* The Logger
*/
private final Logger log = LoggerFactory.getLogger(this.getClass());
/**
* The {@link CharacterService}
*/
private final CharacterService charService;
/**
* The {@link ObjectID} resolver
*/
private final ObjectIDResolver idResolver;
/**
* The {@link ObjectID} being attacked
*/
private int objectId;
/**
* The position of the target
*/
@SuppressWarnings("unused")
private Coordinate origin;
/**
* The attack action type
*/
@SuppressWarnings("unused")
private CharacterAttackAction action;
/**
* Enumeration of all possible attack actions
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public enum CharacterAttackAction {
/**
* Normal click
*/
CLICK(0),
/**
* Clicked with shift-click
*/
SHIFT_CLICK(1);
/**
* The attack action numeric id
*/
public final int id;
/**
* @param id
* the action numeric id
*/
CharacterAttackAction(int id) {
this.id = id;
}
/**
* Resolves the numeric action id to an {@link CharacterAttackAction}
* type
*
* @param id
* the numeric id
* @return the resolved action
*/
public static CharacterAttackAction fromID(int id) {
for (final CharacterAttackAction action : values())
if (action.id == id)
return action;
return null;
}
}
/**
* @param charService
* the character service
* @param idResolver
* the object id resolver
*/
@Inject
public CM_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,145 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. 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.Lineage2Client;
import com.l2jserver.game.net.Lineage2Session;
import com.l2jserver.game.net.packet.AbstractClientPacket;
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.util.BufferUtils;
/**
* This packet is sent by the client once the login server has authorized
* authentication into this server. A new {@link Lineage2Session} object will be
* set to the current connection and the character list is sent to the client.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class CM_AUTH_LOGIN extends AbstractClientPacket {
/**
* The packet OPCODE
*/
public static final int OPCODE = 0x2b;
/**
* The {@link CharacterDAO} implementation
*/
private final CharacterDAO characterDao;
/**
* The {@link AccountID} factory
*/
private final AccountIDProvider accountIdFactory;
// packet
/**
* User account name
*/
private String loginName;
/**
* The play key 1
*/
private int playKey1;
/**
* The play key 2
*/
private int playKey2;
/**
* The login key 1
*/
private int loginKey1;
/**
* The login key 2
*/
private int loginKey2;
/**
* @param characterDao
* the character DAO
* @param accountIdFactory
* the account id factory
*/
@Inject
public CM_AUTH_LOGIN(CharacterDAO characterDao,
AccountIDProvider accountIdFactory) {
this.characterDao = characterDao;
this.accountIdFactory = accountIdFactory;
}
@Override
public void read(Lineage2Client conn, ChannelBuffer buffer) {
this.loginName = BufferUtils.readString(buffer).toLowerCase();
this.playKey1 = buffer.readInt();
this.playKey2 = buffer.readInt();
this.loginKey1 = buffer.readInt();
this.loginKey2 = buffer.readInt();
}
@Override
public void process(final Lineage2Client conn) {
final AccountID accountId = accountIdFactory.resolveID(loginName);
conn.setSession(new Lineage2Session(accountId, playKey1, playKey2,
loginKey1, loginKey2));
final List<L2Character> chars = characterDao.selectByAccount(accountId);
conn.write(SM_CHAR_LIST.fromL2Session(conn.getSession(),
chars.toArray(new L2Character[chars.size()])));
}
/**
* @return the loginName
*/
public String getLoginName() {
return loginName;
}
/**
* @return the playKey1
*/
public int getPlayKey1() {
return playKey1;
}
/**
* @return the playKey2
*/
public int getPlayKey2() {
return playKey2;
}
/**
* @return the loginKey1
*/
public int getLoginKey1() {
return loginKey1;
}
/**
* @return the loginKey2
*/
public int getLoginKey2() {
return loginKey2;
}
}

View File

@@ -0,0 +1,125 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. 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.game.net.Lineage2Client;
import com.l2jserver.game.net.packet.AbstractClientPacket;
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.service.game.character.CannotSetTargetServiceException;
import com.l2jserver.service.game.npc.ActionServiceException;
import com.l2jserver.service.game.npc.NPCService;
import com.l2jserver.util.BufferUtils;
/**
* Executes an bypass command
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class CM_BYPASS extends AbstractClientPacket {
/**
* The logger
*/
private final Logger log = LoggerFactory.getLogger(this.getClass());
/**
* The packet OPCODE
*/
public static final int OPCODE = 0x23;
/**
* The {@link ObjectID} resolver
*/
private final ObjectIDResolver idResolver;
/**
* The {@link NPC} service
*/
private final NPCService npcService;
/**
* The bypass command
*/
private String command;
/**
* @param idResolver
* the object id resolver
* @param npcService
* the {@link NPC} service
*/
@Inject
public CM_BYPASS(ObjectIDResolver idResolver, NPCService npcService) {
this.idResolver = idResolver;
this.npcService = npcService;
}
@Override
public void read(Lineage2Client conn, ChannelBuffer buffer) {
this.command = BufferUtils.readString(buffer);
}
@Override
public void process(final Lineage2Client conn) {
// parse command
final StringTokenizer tokenizer = new StringTokenizer(command, "_ ");
final String type = tokenizer.nextToken();
if (type.equals("npc")) {
final int objectId = Integer.parseInt(tokenizer.nextToken());
final ObjectID<NPC> id = idResolver.resolve(objectId);
if (!(id instanceof NPCID)) {
conn.sendActionFailed();
return;
}
final NPC npc = id.getObject();
try {
npcService.action(npc, conn.getCharacter(),
createArgumentArray(tokenizer));
} catch (ActionServiceException e) {
conn.sendActionFailed();
} catch (CannotSetTargetServiceException e) {
conn.sendActionFailed();
}
} else {
log.warn("Client requested an bypass not supported by server");
}
}
/**
* @param tokenizer
* the tokenizer
* @return an array of strings with each parameter
*/
private String[] createArgumentArray(StringTokenizer tokenizer) {
if (!tokenizer.hasMoreTokens())
return new String[0];
final String[] args = new String[tokenizer.countTokens()];
int i = 0;
while (tokenizer.hasMoreTokens()) {
args[i++] = tokenizer.nextToken();
}
return args;
}
}

View File

@@ -0,0 +1,104 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. 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.Lineage2Client;
import com.l2jserver.game.net.packet.AbstractClientPacket;
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.service.game.character.CannotSetTargetServiceException;
import com.l2jserver.service.game.npc.ActionServiceException;
import com.l2jserver.service.game.npc.NPCService;
import com.l2jserver.util.geometry.Coordinate;
/**
* Executes an action from an character to an NPC
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class CM_CHAR_ACTION extends AbstractClientPacket {
/**
* The packet OPCODE
*/
public static final int OPCODE = 0x1f;
private final ObjectIDResolver idResolver;
private final NPCService npcService;
private int objectId;
@SuppressWarnings("unused")
private Coordinate origin;
private CharacterAction action;
public enum CharacterAction {
CLICK(0),
/**
* This is the right click action.
*/
RIGHT_CLICK(1);
public final int id;
CharacterAction(int id) {
this.id = id;
}
public static CharacterAction fromID(int id) {
for (final CharacterAction action : values())
if (action.id == id)
return action;
return null;
}
}
@Inject
public CM_CHAR_ACTION(ObjectIDResolver idResolver, NPCService npcService) {
this.idResolver = idResolver;
this.npcService = npcService;
}
@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) {
// since this is an erasure type, this is safe.
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(), action);
} catch (ActionServiceException e) {
conn.sendActionFailed();
} catch (CannotSetTargetServiceException e) {
conn.sendActionFailed();
}
}
}

View File

@@ -0,0 +1,61 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. 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.Lineage2Client;
import com.l2jserver.game.net.packet.AbstractClientPacket;
import com.l2jserver.service.game.spawn.CharacterNotTeleportingServiceException;
import com.l2jserver.service.game.spawn.SpawnService;
/**
* Completes the creation of an character. Creates the object, inserts into the
* database and notifies the client about the status of the operation.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class CM_CHAR_APPEARING extends AbstractClientPacket {
/**
* The packet OPCODE
*/
public static final int OPCODE = 0x3a;
/**
* The {@link SpawnService}
*/
private final SpawnService spawnService;
@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,174 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. 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.Lineage2Client;
import com.l2jserver.game.net.packet.AbstractClientPacket;
import com.l2jserver.game.net.packet.server.SM_CHAR_CREATE_FAIL;
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.CharacterInvalidAppearanceException;
import com.l2jserver.service.game.character.CharacterInvalidNameException;
import com.l2jserver.service.game.character.CharacterNameAlreadyExistsException;
import com.l2jserver.service.game.character.CharacterService;
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 = 0x0c;
// 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;
@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, sex,
characterClass, hairStyle, hairColor, face);
if (character != null)
conn.write(SM_CHAR_CREATE_OK.INSTANCE);
else
conn.write(new SM_CHAR_CREATE_FAIL(
SM_CHAR_CREATE_FAIL.Reason.REASON_CREATION_FAILED));
} catch (CharacterInvalidNameException e) {
conn.write(new SM_CHAR_CREATE_FAIL(
SM_CHAR_CREATE_FAIL.Reason.REASON_16_ENG_CHARS));
} catch (CharacterInvalidAppearanceException e) {
conn.write(new SM_CHAR_CREATE_FAIL(
SM_CHAR_CREATE_FAIL.Reason.REASON_CREATION_FAILED));
} catch (CharacterNameAlreadyExistsException e) {
conn.write(new SM_CHAR_CREATE_FAIL(
SM_CHAR_CREATE_FAIL.Reason.REASON_NAME_ALREADY_EXISTS));
}
}
}

View File

@@ -0,0 +1,113 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. 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.Lineage2Client;
import com.l2jserver.game.net.packet.AbstractClientPacket;
import com.l2jserver.game.net.packet.server.SM_STOP;
import com.l2jserver.model.world.L2Character;
import com.l2jserver.service.game.character.CharacterService;
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 = 0x0f;
/**
* The logger
*/
private final Logger log = LoggerFactory.getLogger(this.getClass());
/**
* The {@link CharacterService}
*/
private final CharacterService charService;
// packet
private Coordinate target;
private Coordinate origin;
@SuppressWarnings("unused")
private MovementType type;
public enum MovementType {
MOUSE(0x01), KEYBOARD(0x00);
public final int id;
MovementType(int id) {
this.id = id;
}
public static MovementType fromID(int id) {
for (final MovementType type : values()) {
if (type.id == id)
return type;
}
return null;
}
}
@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_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 l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. 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.Lineage2Client;
import com.l2jserver.game.net.packet.AbstractClientPacket;
import com.l2jserver.game.net.packet.server.SM_CHAR_OPEN_MAP;
/**
* 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 = 0x6c;
@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,63 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. 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.Lineage2Client;
import com.l2jserver.game.net.packet.AbstractClientPacket;
import com.l2jserver.service.game.character.CharacterService;
import com.l2jserver.util.geometry.Point3D;
/**
* 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_POSITION extends AbstractClientPacket {
/**
* The packet OPCODE
*/
public static final int OPCODE = 0x59;
/**
* The {@link CharacterService}
*/
private final CharacterService charService;
private Point3D point;
@SuppressWarnings("unused")
private int extra; // vehicle id
@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,47 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. 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.Lineage2Client;
import com.l2jserver.game.net.packet.AbstractClientPacket;
import com.l2jserver.game.net.packet.server.SM_CHAR_INVENTORY;
import com.l2jserver.model.world.L2Character;
/**
* 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_REQ_INVENTORY extends AbstractClientPacket {
/**
* The packet OPCODE
*/
public static final int OPCODE = 0x14;
@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,74 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. 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.Lineage2Client;
import com.l2jserver.game.net.packet.AbstractClientPacket;
import com.l2jserver.game.net.packet.server.SM_CHAR_SELECTED;
import com.l2jserver.model.dao.CharacterDAO;
import com.l2jserver.model.world.L2Character;
/**
* 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 = 0x12;
// services and daos
/**
* The {@link CharacterDAO} implementation
*/
private final CharacterDAO characterDao;
// packet
/**
* The character slot
*/
private int slot;
@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,93 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. 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.Lineage2Client;
import com.l2jserver.game.net.SystemMessage;
import com.l2jserver.game.net.packet.AbstractClientPacket;
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.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_CHAT extends AbstractClientPacket {
/**
* The packet OPCODE
*/
public static final int OPCODE = 0x49;
// services and daos
/**
* The {@link ChatService} implementation
*/
private final ChatService chatService;
private String message;
private ChatMessageType destination;
private String target;
@Inject
public CM_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,89 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. 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.Lineage2Client;
import com.l2jserver.game.net.packet.AbstractClientPacket;
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;
/**
* 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 = 0x11;
private final Logger log = LoggerFactory.getLogger(CM_ENTER_WORLD.class);
/**
* The {@link CharacterService}
*/
private final CharacterService characterService;
@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 l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. 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.Lineage2Client;
import com.l2jserver.game.net.packet.AbstractClientPacket;
import com.l2jserver.game.net.packet.server.SM_FORT_INFO;
/**
* 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 l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. 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.Lineage2Client;
import com.l2jserver.game.net.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 l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. 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.Lineage2Client;
import com.l2jserver.game.net.packet.AbstractClientPacket;
import com.l2jserver.game.net.packet.server.SM_MANOR_LIST;
/**
* 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 = 0x01;
@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,76 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. 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.game.net.Lineage2Client;
import com.l2jserver.game.net.packet.AbstractClientPacket;
/**
* The client is requesting a logout. Currently, when this packet is received
* the connection is immediately closed.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class CM_EXT_REQ_SHORTCUT_REGISTRY extends AbstractClientPacket {
/**
* The packet OPCODE1
*/
public static final int OPCODE1 = 0xd0;
/**
* The packet OPCODE2
*/
public static final int OPCODE2 = 0x3d;
/**
* The logger
*/
private static final Logger log = LoggerFactory
.getLogger(CM_EXT_REQ_SHORTCUT_REGISTRY.class);
/**
* The shortcut type
*/
@SuppressWarnings("unused")
private int type;
/**
* The shortcut ID
*/
@SuppressWarnings("unused")
private int id;
@SuppressWarnings("unused")
private int slot;
@SuppressWarnings("unused")
private int page;
@SuppressWarnings("unused")
private int lvl;
@SuppressWarnings("unused")
private int characterType;
@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,82 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. 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.Lineage2Client;
import com.l2jserver.game.net.packet.AbstractClientPacket;
import com.l2jserver.service.network.gameguard.GameGuardService;
/**
* 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 = 0xcb;
/**
* 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];
@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,67 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. 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.Lineage2Client;
import com.l2jserver.game.net.packet.AbstractClientPacket;
import com.l2jserver.game.net.packet.server.SM_CHAR_LIST;
import com.l2jserver.model.dao.CharacterDAO;
import com.l2jserver.model.world.L2Character;
/**
* Requests the list of characters to be displayed in the lobby. The list of
* characters is sent to the client.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class 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;
@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[0])));
}
}

View File

@@ -0,0 +1,52 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. 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.game.net.Lineage2Client;
import com.l2jserver.game.net.packet.AbstractClientPacket;
/**
* The client is requesting a logout. Currently, when this packet is received
* the connection is immediately closed.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class CM_LOGOUT extends AbstractClientPacket {
/**
* The packet OPCODE
*/
public static final int OPCODE = 0x00;
/**
* 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,122 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. 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.Lineage2Client;
import com.l2jserver.game.net.Lineage2CryptographyKey;
import com.l2jserver.game.net.ProtocolVersion;
import com.l2jserver.game.net.packet.AbstractClientPacket;
import com.l2jserver.game.net.packet.server.SM_KEY;
import com.l2jserver.service.network.keygen.BlowfishKeygenService;
/**
* 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 = 0x0e;
/**
* 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;
@Inject
public CM_PROTOCOL_VERSION(BlowfishKeygenService keygen) {
this.keygen = keygen;
}
@Override
public void read(Lineage2Client conn, ChannelBuffer buffer) {
this.version = ProtocolVersion.fromVersion((int) buffer
.readUnsignedInt());
}
@Override
public void process(final Lineage2Client conn) {
// generate a new key
final Lineage2CryptographyKey inKey = new Lineage2CryptographyKey(
keygen.generate());
conn.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
conn.getEncrypter().setKey(outKey);
conn.getEncrypter().setEnabled(true);
}
});
}
public ProtocolVersion getVersion() {
return version;
}
}

View File

@@ -0,0 +1,88 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. 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.Lineage2Client;
import com.l2jserver.game.net.packet.AbstractClientPacket;
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;
/**
* 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 = 0x13;
/**
* List of {@link CharacterClass} templates sent to the client
*/
protected 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;
@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,74 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. 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.Lineage2Client;
import com.l2jserver.game.net.packet.AbstractClientPacket;
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;
/**
* 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 = 0x57;
/**
* The {@link CharacterService}
*/
private final CharacterService charService;
/**
* The {@link CharacterDAO}
*/
private final CharacterDAO charDao;
@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 l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.server;
import org.jboss.netty.buffer.ChannelBuffer;
import com.l2jserver.game.net.Lineage2Client;
import com.l2jserver.game.net.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 = 0x1f;
/**
* 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,55 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.server;
import org.jboss.netty.buffer.ChannelBuffer;
import com.l2jserver.game.net.Lineage2Client;
import com.l2jserver.game.net.packet.AbstractServerPacket;
import com.l2jserver.model.world.Actor;
/**
* 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;
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,97 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. 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.game.net.Lineage2Client;
import com.l2jserver.game.net.packet.AbstractServerPacket;
import com.l2jserver.model.server.AttackHit;
import com.l2jserver.model.world.Actor;
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_ATTACK extends AbstractServerPacket {
/**
* The packet OPCODE
*/
public static final int OPCODE = 0x33;
/**
* The attacker actor
*/
private final Actor attacker;
/**
* List of hits to be sent
*/
private final List<AttackHit> hits = CollectionFactory.newList();
public SM_ATTACK(Actor attacker, AttackHit... hits) {
super(OPCODE);
this.attacker = attacker;
Collections.addAll(this.hits, hits);
}
public SM_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());
}
public SM_ATTACK add(AttackHit hit) {
hits.add(hit);
return this;
}
}

View File

@@ -0,0 +1,100 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.server;
import org.jboss.netty.buffer.ChannelBuffer;
import com.l2jserver.game.net.Lineage2Client;
import com.l2jserver.game.net.packet.AbstractServerPacket;
/**
* An packet informing that the character could not be created.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
* @see Reason
*/
public class SM_CHAR_CREATE_FAIL extends AbstractServerPacket {
/**
* The packet OPCODE
*/
public static final int OPCODE = 0x10;
/**
* 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;
Reason(int id) {
this.id = id;
}
}
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,48 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.server;
import org.jboss.netty.buffer.ChannelBuffer;
import com.l2jserver.game.net.Lineage2Client;
import com.l2jserver.game.net.packet.AbstractServerPacket;
/**
* An packet informing that the character was created with success.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class SM_CHAR_CREATE_OK extends AbstractServerPacket {
/**
* The packet OPCODE
*/
public static final int OPCODE = 0x0f;
/**
* The packet shared instance
*/
public static final SM_CHAR_CREATE_OK INSTANCE = new SM_CHAR_CREATE_OK();
public SM_CHAR_CREATE_OK() {
super(OPCODE);
}
@Override
public void write(Lineage2Client conn, ChannelBuffer buffer) {
buffer.writeInt(0x01);
}
}

View File

@@ -0,0 +1,363 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. 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_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_BRACELET;
import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.RIGHT_EAR;
import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.RIGHT_FINGER;
import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.RIGHT_HAND;
import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.UNDERWEAR;
import org.jboss.netty.buffer.ChannelBuffer;
import com.l2jserver.game.net.Lineage2Client;
import com.l2jserver.game.net.packet.AbstractServerPacket;
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.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 = 0x32;
/**
* The character
*/
private L2Character 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(0); // vehicle
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); // load
buffer.writeInt(character.getStats().getMaximumLoad()); // max load
// 20 no weapon, 40 weapon equippe
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);
writePaperdollObjectID(buffer, character, RIGHT_BRACELET);
writePaperdollObjectID(buffer, character, LEFT_BRACELET);
writePaperdollObjectID(buffer, character, DECORATION_1);
writePaperdollObjectID(buffer, character, DECORATION_2);
writePaperdollObjectID(buffer, character, DECORATION_3);
writePaperdollObjectID(buffer, character, DECORATION_4);
writePaperdollObjectID(buffer, character, DECORATION_5);
writePaperdollObjectID(buffer, character, DECORATION_6);
writePaperdollObjectID(buffer, character, BELT);
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); // (max?) talismans count
buffer.writeInt(0x00); // cloak sratus
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());
buffer.writeInt(character.getStats().getWalkSpeed());
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().getMaleCollisionRadius());
buffer.writeDouble(character.getTemplate().getMaleCollisionHeight());
} else {
buffer.writeDouble(character.getTemplate()
.getFemaleCollisionRadius());
buffer.writeDouble(character.getTemplate()
.getFemaleCollisionHeight());
}
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);
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
}
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);
}
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);
}
private void writePaperdollAugumentID(ChannelBuffer buffer,
L2Character character, InventoryPaperdoll paperdoll) {
buffer.writeInt(0x00);
}
}

View File

@@ -0,0 +1,264 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. 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.game.net.Lineage2Client;
import com.l2jserver.game.net.packet.AbstractServerPacket;
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.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;
private final L2Character 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().getMaleCollisionRadius());
buffer.writeDouble(character.getTemplate().getMaleCollisionHeight());
} else {
buffer.writeDouble(character.getTemplate()
.getFemaleCollisionRadius());
buffer.writeDouble(character.getTemplate()
.getFemaleCollisionHeight());
}
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
}
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);
}
private void writePaperdollAugumentID(ChannelBuffer buffer,
L2Character character, InventoryPaperdoll paperdoll) {
buffer.writeInt(0x00);
}
}

View File

@@ -0,0 +1,52 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.server;
import org.jboss.netty.buffer.ChannelBuffer;
import com.l2jserver.game.net.Lineage2Client;
import com.l2jserver.game.net.packet.AbstractServerPacket;
import com.l2jserver.model.world.L2Character;
/**
* 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 OPCODE
*/
public static final int OPCODE = 0xfe;
/**
* The character
*/
private L2Character character;
public SM_CHAR_INFO_EXTRA(L2Character character) {
super(OPCODE);
this.character = character;
}
@Override
public void write(Lineage2Client conn, ChannelBuffer buffer) {
buffer.writeShort(0xcf); // opcode2
buffer.writeInt(character.getID().getID()); // object ID of Player
buffer.writeInt(0x00); // event effect id
}
}

View File

@@ -0,0 +1,101 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.server;
import org.jboss.netty.buffer.ChannelBuffer;
import com.l2jserver.game.net.Lineage2Client;
import com.l2jserver.game.net.packet.AbstractServerPacket;
import com.l2jserver.model.world.Item;
import com.l2jserver.model.world.character.CharacterInventory;
import com.l2jserver.model.world.character.CharacterInventory.InventoryLocation;
/**
* 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 = 0x11;
/**
* The character inventory
*/
private CharacterInventory inventory;
/**
* Whether or not to open the inventory window
*/
private boolean showWindow = false;
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
// TODO implement real item slot
int slot = 0;
for (Item item : inventory) {
if (item.getLocation() == InventoryLocation.WAREHOUSE
|| item.getLocation() == null) {
continue;
}
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() == InventoryLocation.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);
slot++;
}
// TODO inventory block
// buffer.writeShort(_inventory.getBlockItems().length);
// writeC(_inventory.getBlockMode());
// for (int i : _inventory.getBlockItems())
// buffer.writeInt(i);
buffer.writeShort(0x00);
}
}

View File

@@ -0,0 +1,231 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.server;
import static com.l2jserver.game.net.ProtocolVersion.FREYA;
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_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_BRACELET;
import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.RIGHT_EAR;
import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.RIGHT_FINGER;
import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.RIGHT_HAND;
import java.util.Collection;
import org.jboss.netty.buffer.ChannelBuffer;
import com.l2jserver.game.net.Lineage2Client;
import com.l2jserver.game.net.Lineage2Session;
import com.l2jserver.game.net.packet.AbstractServerPacket;
import com.l2jserver.model.world.Item;
import com.l2jserver.model.world.L2Character;
import com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll;
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 = 0x09;
/**
* 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;
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;
}
public static SM_CHAR_LIST fromL2Session(Lineage2Session session,
L2Character... characters) {
return new SM_CHAR_LIST(session.getAccountID().getID(),
session.getPlayKey2(), -1, characters);
}
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.writeByte(0x09);
buffer.writeInt(characters.length);
// Can prevent players from creating new characters (if 0);
// if 1 the client will ask if chars may be created
// (RequestCharacterTemplatesPacket) Response: (CharacterTemplatePacket)
buffer.writeInt(7); // max chars
buffer.writeByte(0x00);
// int i = 0;
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() : 0x00)); // clan id
buffer.writeInt(0x00); // ??
buffer.writeInt(character.getSex().option); // sex
buffer.writeInt(character.getRace().id); // race
// if (character.getClassId() == character.getBaseClassId())
buffer.writeInt(character.getCharacterClass().id); // base class id
// or class id
// else
// buffer.writeInt(character.getBaseClassId());
buffer.writeInt(1); // active ??
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(character.getPkKills()); // pk
buffer.writeInt(character.getPvpKills()); // pvp
for (int n = 0; n < 7; n++) {
buffer.writeInt(0x00); // unk
}
// buffer.writeInt(0x00); // unk 1
// buffer.writeInt(0x00); // unk 2
// buffer.writeInt(0x00); // unk 3
// buffer.writeInt(0x00); // unk 4
// buffer.writeInt(0x00); // unk 5
// buffer.writeInt(0x00); // unk 6
// buffer.writeInt(0x00); // unk 7
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);
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);
// hair style
buffer.writeInt(character.getAppearance().getHairStyle().option);
// hair color
buffer.writeInt(character.getAppearance().getHairColor().option);
// face
buffer.writeInt(character.getAppearance().getFace().option);
buffer.writeDouble(character.getStats().getMaxHP()); // hp max
buffer.writeDouble(character.getStats().getMaxMP()); // mp max
buffer.writeInt(0x0); // seconds left before delete
buffer.writeInt(character.getCharacterClass().id); // class
buffer.writeInt(1); // c3 auto-select char
buffer.writeByte(0x00); // enchant effect
buffer.writeInt(0x00); // augmentation id
// Currently on retail when you are on character select you don't
// see your transformation.
buffer.writeInt(0x00);
// Freya by Vistall:
if (conn.supports(FREYA)) {
// npdid - 16024 Tame Tiny Baby Kookaburra
buffer.writeInt(16024); // A9E89C
buffer.writeInt(0); // level
buffer.writeInt(0); // ?
buffer.writeInt(0); // food? - 1200
buffer.writeDouble(0); // max Hp
buffer.writeDouble(0); // cur Hp
}
}
}
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,50 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.server;
import org.jboss.netty.buffer.ChannelBuffer;
import com.l2jserver.game.net.Lineage2Client;
import com.l2jserver.game.net.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 = 0xa3;
/**
* The map ID
*/
private final int mapID;
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,57 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.server;
import org.jboss.netty.buffer.ChannelBuffer;
import com.l2jserver.game.net.Lineage2Client;
import com.l2jserver.game.net.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 = 0x71;
/**
* The restart state
*/
private boolean state;
public SM_CHAR_RESTART(boolean state) {
super(OPCODE);
this.state = state;
}
public static SM_CHAR_RESTART ok() {
return new SM_CHAR_RESTART(true);
}
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));
}
}

View File

@@ -0,0 +1,93 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.server;
import org.jboss.netty.buffer.ChannelBuffer;
import com.l2jserver.game.net.Lineage2Client;
import com.l2jserver.game.net.packet.AbstractServerPacket;
import com.l2jserver.model.world.L2Character;
import com.l2jserver.model.world.actor.ActorExperience;
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 = 0x0b;
/**
* The selected character
*/
private final L2Character 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());
buffer.writeInt(0); // game time
buffer.writeInt(0x00); // unk
buffer.writeInt(character.getCharacterClass().id);
buffer.writeInt(0x00);// unk
buffer.writeInt(0x00);// unk
buffer.writeInt(0x00);// unk
buffer.writeInt(0x00);// unk
buffer.writeBytes(new byte[64]); // unk
buffer.writeInt(0x00);// unk
}
}

View File

@@ -0,0 +1,72 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.server;
import org.jboss.netty.buffer.ChannelBuffer;
import com.l2jserver.game.net.Lineage2Client;
import com.l2jserver.game.net.packet.AbstractServerPacket;
import com.l2jserver.model.template.CharacterTemplate;
/**
* An packet that sends all character templates to the client.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class SM_CHAR_TEMPLATE extends AbstractServerPacket {
/**
* The packet OPCODE
*/
public static final int OPCODE = 0x0d;
/**
* The character template list
*/
private CharacterTemplate[] 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.getRace().id);
buffer.writeInt(template.getCharacterClass().id);
buffer.writeInt(0x46);
buffer.writeInt(template.getBaseStrength());
buffer.writeInt(0x0a);
buffer.writeInt(0x46);
buffer.writeInt(template.getBaseDexterity());
buffer.writeInt(0x0a);
buffer.writeInt(0x46);
buffer.writeInt(template.getBaseConcentration());
buffer.writeInt(0x0a);
buffer.writeInt(0x46);
buffer.writeInt(template.getBaseIntelligence());
buffer.writeInt(0x0a);
buffer.writeInt(0x46);
buffer.writeInt(template.getBaseWitness());
buffer.writeInt(0x0a);
buffer.writeInt(0x46);
buffer.writeInt(template.getBaseMentality());
buffer.writeInt(0x0a);
}
}
}

View File

@@ -0,0 +1,86 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.server;
import org.jboss.netty.buffer.ChannelBuffer;
import com.l2jserver.game.net.Lineage2Client;
import com.l2jserver.game.net.packet.AbstractServerPacket;
import com.l2jserver.model.world.Actor;
import com.l2jserver.model.world.L2Character;
import com.l2jserver.service.game.chat.ChatMessageType;
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_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;
public SM_CHAT(Actor character, ChatMessageType destination, String message) {
super(OPCODE);
this.actor = character;
this.destination = destination;
this.message = message;
}
public SM_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,64 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. 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.game.net.Lineage2Client;
import com.l2jserver.game.net.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;
public SM_COMMUNITY_HTML(String html) {
super(OPCODE);
this.html = html;
}
public SM_COMMUNITY_HTML(Html html) {
super(OPCODE);
this.html = html.toHtml();
}
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,58 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.server;
import org.jboss.netty.buffer.ChannelBuffer;
import com.l2jserver.game.net.Lineage2Client;
import com.l2jserver.game.net.packet.AbstractServerPacket;
import com.l2jserver.model.server.AttackHit;
import com.l2jserver.model.world.Actor;
/**
* This packet informs the client of an attack issued
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
* @see AttackHit
*/
public class SM_DIE extends AbstractServerPacket {
/**
* The packet OPCODE
*/
public static final int OPCODE = 0x00;
/**
* The attacker actor
*/
private final Actor actor;
public SM_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,104 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.server;
import org.jboss.netty.buffer.ChannelBuffer;
import com.l2jserver.game.net.Lineage2Client;
import com.l2jserver.game.net.packet.AbstractServerPacket;
import com.l2jserver.model.world.L2Character;
import com.l2jserver.model.world.actor.ActorExperience;
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_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_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,54 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.server;
import org.jboss.netty.buffer.ChannelBuffer;
import com.l2jserver.game.net.Lineage2Client;
import com.l2jserver.game.net.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;
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,61 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. 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.game.net.Lineage2Client;
import com.l2jserver.game.net.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 = 0x74;
private final int[] key;
public SM_GG_QUERY(int[] key) {
super(OPCODE);
Preconditions.checkArgument(key.length == 4,
"key must by an 4-length array");
this.key = key;
}
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,72 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. 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.game.net.Lineage2Client;
import com.l2jserver.game.net.packet.AbstractServerPacket;
import com.l2jserver.model.world.NPC;
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 = 0x19;
/**
* The saying NPC
*/
private final NPC npc;
/**
* The HTML contents
*/
private final String html;
public SM_HTML(NPC npc, String html) {
super(OPCODE);
this.npc = npc;
this.html = html;
}
public SM_HTML(NPC npc, Html html) {
super(OPCODE);
this.npc = npc;
this.html = html.toHtml();
}
public SM_HTML(NPC npc, HtmlTemplate template) {
super(OPCODE);
this.npc = npc;
this.html = template.toHtmlString();
}
@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,54 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.server;
import org.jboss.netty.buffer.ChannelBuffer;
import com.l2jserver.game.net.Lineage2Client;
import com.l2jserver.game.net.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;
public SM_ITEM_GROUND() {
super(OPCODE);
}
@Override
public void write(Lineage2Client conn, ChannelBuffer buffer) {
buffer.writeInt(268437456); // char who dropped
buffer.writeInt(268635461); // item obj id
buffer.writeInt(57); // item template id
buffer.writeInt(-84341); // x
buffer.writeInt(244623); // y
buffer.writeInt(-3728); // z
// only show item count if it is a stackable item
buffer.writeInt(0x01); // show count
buffer.writeLong(4001); // count
buffer.writeInt(1); // unknown
}
}

View File

@@ -0,0 +1,122 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. 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.game.net.Lineage2Client;
import com.l2jserver.game.net.Lineage2CryptographyKey;
import com.l2jserver.game.net.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 = 0x2e;
/**
* 8-byte key cryptography key
*/
private byte[] key;
/**
* The protocol state. True if valid, false if not.
*/
private boolean 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
}
/**
* @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,56 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.server;
import org.jboss.netty.buffer.ChannelBuffer;
import com.l2jserver.game.net.Lineage2Client;
import com.l2jserver.game.net.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 OPCODE
*/
public static final int OPCODE = 0xfe;
/**
* List of manors to be sent
*/
private String[] manors;
public SM_MANOR_LIST(String... manors) {
super(OPCODE);
this.manors = manors;
}
@Override
public void write(Lineage2Client conn, ChannelBuffer buffer) {
buffer.writeShort(0x22);
buffer.writeInt(manors.length);
int i = 1;
for (String manor : manors) {
buffer.writeInt(i++);
BufferUtils.writeString(buffer, manor);
}
}
}

View File

@@ -0,0 +1,68 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.server;
import org.jboss.netty.buffer.ChannelBuffer;
import com.l2jserver.game.net.Lineage2Client;
import com.l2jserver.game.net.packet.AbstractServerPacket;
import com.l2jserver.model.world.Actor;
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_MOVE extends AbstractServerPacket {
/**
* The packet OPCODE
*/
public static final int OPCODE = 0x2f;
/**
* The selected character
*/
private final Actor actor;
/**
* The destination coordinate
*/
private Coordinate target;
public SM_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,52 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.server;
import org.jboss.netty.buffer.ChannelBuffer;
import com.l2jserver.game.net.Lineage2Client;
import com.l2jserver.game.net.packet.AbstractServerPacket;
import com.l2jserver.model.world.L2Character;
/**
* This packet updates the movement type
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class SM_MOVE_TYPE extends AbstractServerPacket {
/**
* The packet OPCODE
*/
public static final int OPCODE = 0x28;
/**
* The character
*/
private final L2Character character;
public SM_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,114 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.server;
import org.jboss.netty.buffer.ChannelBuffer;
import com.l2jserver.game.net.Lineage2Client;
import com.l2jserver.game.net.packet.AbstractServerPacket;
import com.l2jserver.model.template.NPCTemplate;
import com.l2jserver.model.world.NPC;
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 = 0x0c;
private final NPC 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
// if (npc instanceof NPC) {
buffer.writeInt((template.isAttackable() ? 0x01 : 0x00));
// } else {
// buffer.writeInt(0x01);
// }
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
buffer.writeDouble(0x01);// TODO
buffer.writeDouble(template.getCollisionRadius());
buffer.writeDouble(template.getCollisionHeight());
buffer.writeInt((template.getRightHand() != null ? template
.getRightHand().getID() : 0x00));
buffer.writeInt(0x00); // chest
buffer.writeInt((template.getLeftHand() != null ? template
.getLeftHand().getID() : 0x00));
buffer.writeByte(1); // name above char 1=true ... ??
buffer.writeByte(0x00); // 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.getName());
BufferUtils.writeString(buffer, template.getTitle());
buffer.writeInt(0x00); // Title color 0=client default
buffer.writeInt(0x00); // pvp flag
buffer.writeInt(0x00); // karma
buffer.writeInt(0x00); // C2 - abnormal effect
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
buffer.writeDouble(template.getCollisionRadius());
buffer.writeDouble(template.getCollisionHeight());
buffer.writeInt(0x00); // C4 - enchant effect
buffer.writeInt(0x00); // C6 -- is flying
buffer.writeInt(0x00); // unk
buffer.writeInt(0x00);// CT1.5 Pet form and skills, Color effect
buffer.writeByte((template.getDisplayName() ? 0x01 : 0x00)); // hide
// name
buffer.writeByte((template.getDisplayName() ? 0x01 : 0x00)); // hide
// name,
// again
buffer.writeInt(0x00); // special effects
buffer.writeInt(0x00); // display effect
}
}

View File

@@ -0,0 +1,52 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.server;
import org.jboss.netty.buffer.ChannelBuffer;
import com.l2jserver.game.net.Lineage2Client;
import com.l2jserver.game.net.packet.AbstractServerPacket;
import com.l2jserver.model.world.PositionableObject;
/**
* 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;
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,68 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.server;
import org.jboss.netty.buffer.ChannelBuffer;
import com.l2jserver.game.net.Lineage2Client;
import com.l2jserver.game.net.packet.AbstractServerPacket;
import com.l2jserver.model.template.NPCTemplate;
import com.l2jserver.model.world.NPC;
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;
private final NPC 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.getName()); // name
buffer.writeInt((template.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.getCollisionRadius());
buffer.writeDouble(template.getCollisionHeight());
buffer.writeInt((int) (template.isAttackable() ? npc.getHP() : 0x00));
buffer.writeInt((int) (template.isAttackable() ? template
.getMaximumHP() : 0x00));
buffer.writeInt(0x01); // object type
buffer.writeInt(0x00); // special effects
}
}

View File

@@ -0,0 +1,90 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. 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.game.net.Lineage2Client;
import com.l2jserver.game.net.packet.AbstractServerPacket;
import com.l2jserver.model.world.Actor;
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_STATUS_UPDATE extends AbstractServerPacket {
/**
* The packet OPCODE
*/
public static final int OPCODE = 0x18;
/**
* The stats the can be updated with the packet
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public enum Stat {
LEVEL(0x01), EXPERIENCE(0x02), STR(0x03), DEX(0x04), CON(0x05), INT(
0x06), WIT(0x07), MEN(0x08),
HP(0x09), MAX_HP(0x0a), MP(0x0b), MAX_MP(0x0c),
SP(0x0d), LOAD(0x0e), MAX_LOAD(0x0f),
PHYSICAL_ATK(0x11), ATTACK_SPEED(0x12), PHYSICAL_DEFENSE(0x13), EVASION(
0x14), ACCURACY(0x15), CRITICAL(0x16), MAGICAL_ATTACK(0x17), CAST_SPEED(
0x18), MAGICAL_DEFENSE(0x19), PVP_FLAG(0x1a), KARMA(0x1b),
CP(0x21), MAX_CP(0x22);
public final int id;
Stat(int id) {
this.id = id;
}
}
private final Map<Stat, Integer> update = CollectionFactory.newMap();
private final Actor actor;
public SM_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());
}
}
public SM_STATUS_UPDATE add(Stat stat, int value) {
update.put(stat, value);
return this;
}
}

View File

@@ -0,0 +1,51 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.server;
import org.jboss.netty.buffer.ChannelBuffer;
import com.l2jserver.game.net.Lineage2Client;
import com.l2jserver.game.net.packet.AbstractServerPacket;
import com.l2jserver.model.world.L2Character;
/**
* An packet that sends all character templates to the client.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class SM_STOP extends AbstractServerPacket {
/**
* The packet OPCODE
*/
public static final int OPCODE = 0x47;
private L2Character character;
public SM_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,262 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. 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.game.net.Lineage2Client;
import com.l2jserver.game.net.SystemMessage;
import com.l2jserver.game.net.packet.AbstractServerPacket;
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.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 = 0x62;
/**
* The System message id
*/
private int id;
/**
* The system message parameters
*/
private List<SystemMessagePacketParameter> params = CollectionFactory
.newList();
public interface SystemMessagePacketParameter {
public static final byte TYPE_SYSTEM_STRING = 13;
public static final byte TYPE_PLAYER_NAME = 12;
// id 11 - unknown
public static final byte TYPE_INSTANCE_NAME = 10;
public static final byte TYPE_ELEMENT_NAME = 9;
// id 8 - same as 3
public static final byte TYPE_ZONE_NAME = 7;
public static final byte TYPE_ITEM_NUMBER = 6;
public static final byte TYPE_CASTLE_NAME = 5;
public static final byte TYPE_SKILL_NAME = 4;
public static final byte TYPE_ITEM_NAME = 3;
public static final byte TYPE_NPC_NAME = 2;
public static final byte TYPE_NUMBER = 1;
public static final byte TYPE_TEXT = 0;
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);
}
}
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;
}
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;
}
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;
}
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;
}
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;
}
public final SM_SYSTEM_MESSAGE addItem(final Item item) {
return addItem(item.getTemplateID().getTemplate());
}
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;
}
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;
}
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,59 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.server;
import org.jboss.netty.buffer.ChannelBuffer;
import com.l2jserver.game.net.Lineage2Client;
import com.l2jserver.game.net.packet.AbstractServerPacket;
import com.l2jserver.model.world.Actor;
/**
* 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_TARGET extends AbstractServerPacket {
/**
* The packet OPCODE
*/
public static final int OPCODE = 0xb9;
/**
* The selected character
*/
private final Actor object;
private int color;
public SM_TARGET(Actor object, int color) {
super(OPCODE);
this.object = object;
this.color = color;
}
public SM_TARGET(Actor object) {
this(object, 0);
}
@Override
public void write(Lineage2Client conn, ChannelBuffer buffer) {
buffer.writeInt(object.getID().getID());
buffer.writeShort(color);
buffer.writeInt(0x00);
}
}

View File

@@ -0,0 +1,62 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net.packet.server;
import org.jboss.netty.buffer.ChannelBuffer;
import com.l2jserver.game.net.Lineage2Client;
import com.l2jserver.game.net.packet.AbstractServerPacket;
import com.l2jserver.model.world.L2Character;
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_TELEPORT extends AbstractServerPacket {
/**
* The packet OPCODE
*/
public static final int OPCODE = 0x22;
/**
* The selected character
*/
private final L2Character character;
/**
* The teleportation point
*/
private final Point3D point;
public SM_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,110 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.model;
import com.google.common.base.Preconditions;
import com.l2jserver.model.id.ID;
/**
* Simple model interface implementing {@link ID} related methods
*
* @param <T>
* the ID type used to represent this {@link Model}
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public abstract class AbstractModel<T extends ID<?>> implements Model<T> {
/**
* The object id
*/
protected T id;
/**
* The database object state
*/
protected transient ObjectDesire desire = ObjectDesire.INSERT;
@Override
public T getID() {
return id;
}
@Override
public void setID(T ID) {
Preconditions.checkState(id == null, "ID is already set");
desireInsert();
this.id = ID;
}
@Override
public ObjectDesire getObjectDesire() {
return desire;
}
@Override
public void setObjectDesire(ObjectDesire desire) {
if (desire == null)
desire = ObjectDesire.NONE;
this.desire = desire;
}
/**
* Set this object desire to {@link ObjectDesire#UPDATE}. If the desire is
* {@link ObjectDesire#INSERT} or {@link ObjectDesire#DELETE} the desire
* will not be changed.
*/
@SuppressWarnings("javadoc")
protected void desireUpdate() {
if (this.desire != ObjectDesire.INSERT
&& this.desire != ObjectDesire.DELETE)
this.desire = ObjectDesire.UPDATE;
}
/**
* Set this object desire to {@link ObjectDesire#INSERT}. If the desire is
* {@link ObjectDesire#DELETE} the desire will not be changed.
*/
@SuppressWarnings("javadoc")
protected void desireInsert() {
if (this.desire != ObjectDesire.DELETE)
this.desire = ObjectDesire.INSERT;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
AbstractModel<?> other = (AbstractModel<?>) obj;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
return true;
}
}

View File

@@ -0,0 +1,104 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.model;
import com.l2jserver.model.id.ID;
import com.l2jserver.service.database.DatabaseService;
/**
* Base model. Each object model must implement this interface to be able to be
* inserted into the database.
*
* @param <T>
* the {@link ID} type used to represent this {@link Model}
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public interface Model<T extends ID<?>> {
/**
* @return the object ID
*/
T getID();
/**
* Please note that the ID can only be set one time. Once it has been set,
* it cannot be changed and a {@link IllegalStateException} will be thrown
* if trying to change the ID.
*
* @param ID
* the object ID to set
* @throws IllegalStateException
* if the ID was already set
*/
void setID(T ID) throws IllegalStateException;
/**
* Each object has an desire. Desires express what the
* {@link DatabaseService} should do with the object. The service
* automatically keep tracks of every database object (and release them when
* they are garbage collected).
*
* @return the database object desire
*/
ObjectDesire getObjectDesire();
/**
* Each object has an desire. Desires express what the
* {@link DatabaseService} should do with the object. The service
* automatically keep tracks of every database object (and release them when
* they are garbage collected).
*
* @param desire
* the database object desire to set
*/
void setObjectDesire(ObjectDesire desire);
/**
* Indicated what the object wants to do in the database. It indicates
* whether the object should be inserted, updated or deleted from the
* database.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public enum ObjectDesire {
/**
* Don't do anything
*/
NONE,
/**
* Insert a new object into database.
* <p>
* If the primary key is auto generated by the database a clone of this
* object will be created.<br>
* If the primary key is <b>not</b> auto generated by the database, an
* database exception will occur.
*/
INSERT,
/**
* Updates the object in the database.
* <p>
* If the object is not in the database nothing will happen.
*/
UPDATE,
/**
* Deletes the object from the database.
* <p>
* If tge object is not in the database nothing will happen.
*/
DELETE;
}
}

View File

@@ -0,0 +1,62 @@
/*
* This file is part of l2jserver <l2jserver.com>.
*
* l2jserver 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.
*
* l2jserver 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 l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.model.dao;
import java.util.List;
import com.l2jserver.model.id.AccountID;
import com.l2jserver.model.id.object.CharacterID;
import com.l2jserver.model.world.Clan;
import com.l2jserver.model.world.L2Character;
import com.l2jserver.service.cache.Cacheable;
import com.l2jserver.service.database.DataAccessObject;
/**
* The {@link CharacterDAO} is can load and save {@link Character character
* instances} .
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public interface CharacterDAO extends
DataAccessObject<L2Character, CharacterID>, Cacheable {
/**
* Load the members of the given <tt>clan</tt>
*
* @param clan
* the clan
*/
void load(Clan clan);
/**
* Select an character by its name.
*
* @param name
* the character name
* @return the found character. Null if does not exists.
*/
L2Character selectByName(String name);
/**
* Select an character by its name.
*
* @param account
* the account id
* @return the found characters. An empty list if this account has no
* characters.
*/
List<L2Character> selectByAccount(AccountID account);
}

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