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

Change-Id: I375a10c9d7ce56df457a998e5cb9d02465865973

This commit is contained in:
rogiel
2011-04-29 20:17:57 -03:00
parent 0662150229
commit f1d8e6588f
16 changed files with 825 additions and 0 deletions

View File

@@ -0,0 +1,76 @@
package com.l2jserver.game.net.packet.client;
import java.nio.charset.Charset;
import org.jboss.netty.buffer.ChannelBuffer;
import com.google.inject.Inject;
import com.l2jserver.game.net.Lineage2Connection;
import com.l2jserver.game.net.packet.AbstractClientPacket;
import com.l2jserver.service.game.world.WorldService;
public class AuthLoginPacket extends AbstractClientPacket {
public static final int OPCODE = 0x0e;
@Inject
private WorldService world;
// packet
private String loginName;
private int playKey1;
private int playKey2;
private int loginKey1;
private int loginKey2;
@Override
public void read(ChannelBuffer buffer) {
this.loginName = buffer.readBytes(buffer.bytesBefore((byte) 0x00))
.toString(Charset.defaultCharset());
this.playKey1 = buffer.readInt();
this.playKey2 = buffer.readInt();
this.loginKey1 = buffer.readInt();
this.loginKey2 = buffer.readInt();
}
@Override
public void process(final Lineage2Connection conn) {
// assume it is correct, for now
// send character list
world.getEventDispatcher().dispatch(null);
}
/**
* @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,185 @@
package com.l2jserver.game.net.packet.server;
import org.jboss.netty.buffer.ChannelBuffer;
import com.l2jserver.game.net.packet.AbstractServerPacket;
public class CharSelectionInfoPacket extends AbstractServerPacket {
public static final int OPCODE = 0x09;
private final String loginName;
private final int sessionId;
private final int activeId;
private final Character[] characters;
public CharSelectionInfoPacket(int opcode, String loginName, int sessionId,
int activeId, Character... characters) {
super(opcode);
this.loginName = loginName;
this.sessionId = sessionId;
this.activeId = activeId;
this.characters = characters;
}
@Override
public void write(ChannelBuffer buffer) {
// buffer.writeByte(0x09);
// int size = (characters.length);
// buffer.writeInt(size);
//
// // Can prevent players from creating new characters (if 0); (if 1,
// the client will ask if chars may be created (0x13) Response: (0x0D) )
// buffer.writeInt(0x07);
// buffer.writeByte(0x00);
//
// long lastAccess = 0L;
//
// // if (activeId == -1) {
// // for (int i = 0; i < size; i++) {
// // if (lastAccess < characters[i].getLastAccess()) {
// // lastAccess = characters[i].getLastAccess();
// // _activeId = i;
// // }
// // }
// // }
//
// for (int i = 0; i < size; i++)
// {
// Character character = characters[i];
//
// buffer.writeBytes(character.getName());
// buffer.writeInt(character.getCharId());
// writeS(_loginName);
// buffer.writeInt(_sessionId);
// buffer.writeInt(character.getClanId());
// buffer.writeInt(0x00); // ??
//
// buffer.writeInt(character.getSex());
// buffer.writeInt(character.getRace());
//
// if (character.getClassId() == character.getBaseClassId())
// buffer.writeInt(character.getClassId());
// else
// buffer.writeInt(character.getBaseClassId());
//
// buffer.writeInt(0x01); // active ??
//
// buffer.writeInt(character.getX()); // x
// buffer.writeInt(character.getY()); // y
// buffer.writeInt(character.getZ()); // z
//
// buffer.writeDouble(character.getCurrentHp()); // hp cur
// buffer.writeDouble(character.getCurrentMp()); // mp cur
//
// buffer.writeInt(character.getSp());
// writeQ(character.getExp());
// buffer.writeInt(character.getLevel());
//
// buffer.writeInt(character.getKarma()); // karma
// buffer.writeInt(character.getPkKills());
//
// buffer.writeInt(character.getPvPKills());
// buffer.writeInt(0x00);
// buffer.writeInt(0x00);
// buffer.writeInt(0x00);
// buffer.writeInt(0x00);
// buffer.writeInt(0x00);
// buffer.writeInt(0x00);
// buffer.writeInt(0x00);
//
//
// for(int id = 0; id <27; id++) {
// buffer.writeInt(0x00);
// }
// //
// buffer.writeInt(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_HAIR));
// //
// buffer.writeInt(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_REAR));
// //
// buffer.writeInt(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_LEAR));
// //
// buffer.writeInt(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_NECK));
// //
// buffer.writeInt(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_RFINGER));
// //
// buffer.writeInt(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_LFINGER));
// //
// buffer.writeInt(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_HEAD));
// //
// buffer.writeInt(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_RHAND));
// //
// buffer.writeInt(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_LHAND));
// //
// buffer.writeInt(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_GLOVES));
// //
// buffer.writeInt(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_CHEST));
// //
// buffer.writeInt(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_LEGS));
// //
// buffer.writeInt(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_FEET));
// //
// buffer.writeInt(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_CLOAK));
// //
// buffer.writeInt(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_RHAND));
// //
// buffer.writeInt(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_HAIR));
// //
// buffer.writeInt(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_HAIR2));
// //
// buffer.writeInt(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_RBRACELET));
// //
// buffer.writeInt(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_LBRACELET));
// //
// buffer.writeInt(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_DECO1));
// //
// buffer.writeInt(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_DECO2));
// //
// buffer.writeInt(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_DECO3));
// //
// buffer.writeInt(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_DECO4));
// //
// buffer.writeInt(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_DECO5));
// //
// buffer.writeInt(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_DECO6));
// //
// buffer.writeInt(charInfoPackage.getPaperdollItemId(Inventory.PAPERDOLL_BELT));
//
// buffer.writeInt(character.getHairStyle());
// buffer.writeInt(character.getHairColor());
// buffer.writeInt(character.getFace());
//
// buffer.writeDouble(character.getMaxHp()); // hp max
// buffer.writeDouble(character.getMaxMp()); // mp max
//
// long deleteTime = character.getDeleteTimer();
// int deletedays = 0;
// if (deleteTime > 0)
// deletedays = (int)((deleteTime-System.currentTimeMillis())/1000);
// buffer.writeInt(deletedays); // days left before
// // delete .. if != 0
// // then char is inactive
// buffer.writeInt(character.getClassId());
// if (i == _activeId)
// buffer.writeInt(0x01);
// else
// buffer.writeInt(0x00); //c3 auto-select char
//
// buffer.writeByte(character.getEnchantEffect() > 127 ? 127 :
// character.getEnchantEffect());
//
// buffer.writeInt(character.getAugmentationId());
//
// //buffer.writeInt(charInfoPackage.getTransformId()); // Used to
// display Transformations
// buffer.writeInt(0x00); // Currently on retail when you are on
// character select you don't see your transformation.
//
// // Freya by Vistall:
// buffer.writeInt(0); // npdid - 16024 Tame Tiny Baby Kookaburra A9E89C
// buffer.writeInt(0); // level
// buffer.writeInt(0); // ?
// buffer.writeInt(0); // food? - 1200
// buffer.writeDouble(0); // max Hp
// buffer.writeDouble(0); // cur Hp
}
}

View File

@@ -0,0 +1,102 @@
package com.l2jserver.game.net.packet.server;
import java.util.Arrays;
import org.jboss.netty.buffer.ChannelBuffer;
import com.l2jserver.game.net.packet.AbstractServerPacket;
/**
* <h1>0x2e "KeyPacket"</h1>
* <p>
* byte[8] key<br>
* byte protocolStatus
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class KeyPacket extends AbstractServerPacket {
/**
* Message 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 KeyPacket(byte[] key, boolean status) {
super(OPCODE);
this.key = Arrays.copyOfRange(key, 0, 8);
this.status = status;
}
/**
* Creates a new {@link KeyPacket} with <tt>key</tt> and valid protocol.
*
* @param key
* the key
* @return the new instance
*/
public static KeyPacket valid(byte[] key) {
return new KeyPacket(key, true);
}
/**
* Creates a new {@link KeyPacket} with <tt>key</tt> and invalid protocol.
*
* @param key
* the key
* @return the new instance
*/
public static KeyPacket invalid(byte[] key) {
return new KeyPacket(key, false);
}
@Override
public void write(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,144 @@
package com.l2jserver.model.world;
import java.util.List;
import com.l2jserver.model.template.SkillTemplate;
import com.l2jserver.model.template.capability.Attackable;
import com.l2jserver.model.world.actor.ActorEvent;
import com.l2jserver.model.world.actor.ActorListener;
import com.l2jserver.model.world.capability.Actor;
import com.l2jserver.model.world.capability.Attacker;
import com.l2jserver.model.world.capability.Castable;
import com.l2jserver.model.world.capability.Equipable;
import com.l2jserver.model.world.capability.Equiper;
import com.l2jserver.util.Coordinate;
import com.l2jserver.util.factory.CollectionFactory;
public abstract class AbstractActor extends AbstractObject implements Actor {
private final List<ActorListener> listeners = CollectionFactory
.newList(ActorListener.class);
protected int level;
protected int hp;
protected Coordinate position;
@Override
public void receiveDamage(int damage) {
// TODO Auto-generated method stub
}
@Override
public int getHP() {
return hp;
}
@Override
public void setHP(int hp) {
this.hp = hp;
}
@Override
public void receiveAttack(Attacker attacker, Attackable weapon) {
// TODO
}
@Override
public void attack(com.l2jserver.model.world.capability.Attackable target,
Attackable weapon) {
// TODO
}
@Override
public void cast() {
// TODO
}
@Override
public void cast(SkillTemplate skill, Castable cast) {
// TODO
}
@Override
public void spawn(Coordinate coordinate) {
// TODO
}
@Override
public boolean isSpawned() {
return false;
}
@Override
public Coordinate getPosition() {
return position;
}
@Override
public void setPosition(Coordinate coord) {
this.position = coord;
}
@Override
public int getLevel() {
return level;
}
@Override
public void setLevel(int level) {
this.level = level;
}
@Override
public void die(WorldObject killer) {
// TODO
}
@Override
public void equip(Equipable equipable) {
// TODO
}
@Override
public boolean isEquiped(Equipable equipment) {
return false;
}
@Override
public boolean isEquiped(
com.l2jserver.model.template.capability.Equipable equipable) {
return false;
}
@Override
public void setEquipment(Object slot, Equipable equipment) {
// TODO
}
@Override
public void getEquipment(Object slot) {
// TODO
}
@Override
public void equip(Equiper equiper) {
// TODO
}
@Override
public void addListener(ActorListener listener) {
listeners.add(listener);
}
@Override
public void removeListener(ActorListener listener) {
listeners.remove(listener);
}
@Override
public void dispatch(ActorEvent e) {
for (final ActorListener listener : listeners) {
listener.dispatch(e);
}
}
}

View File

@@ -0,0 +1,8 @@
package com.l2jserver.model.world.actor;
import com.l2jserver.model.world.capability.Actor;
import com.l2jserver.model.world.event.WorldEvent;
public interface ActorEvent extends WorldEvent {
Actor getActor();
}

View File

@@ -0,0 +1,6 @@
package com.l2jserver.model.world.actor;
import com.l2jserver.model.world.event.WorldListener;
public interface ActorListener extends WorldListener<ActorEvent> {
}

View File

@@ -0,0 +1,17 @@
package com.l2jserver.model.world.capability;
import com.l2jserver.model.world.AbstractObject;
import com.l2jserver.model.world.actor.ActorEvent;
import com.l2jserver.model.world.actor.ActorListener;
/**
* Defines an {@link AbstractObject} that defines an Actor (NPC, player, pet,
* etc...)
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public interface Actor extends Listenable<ActorListener, ActorEvent>,
Spawnable, Positionable, Damagable, Attackable, Attacker, Castable,
Caster, Levelable, Killable, Equiper, Equipable {
}

View File

@@ -0,0 +1,14 @@
package com.l2jserver.model.world.capability;
import com.l2jserver.model.world.AbstractObject;
/**
* Defines an {@link AbstractObject} that can become invisible to other objects.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public interface Invisible extends ObjectCapability {
boolean isInvisible();
void setInvisible();
}

View File

@@ -0,0 +1,11 @@
package com.l2jserver.model.world.capability;
import com.l2jserver.model.world.AbstractObject;
/**
* Defines an {@link AbstractObject} that can talk to an {@link Conversable}.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public interface Talker extends ObjectCapability {
}

View File

@@ -0,0 +1,15 @@
package com.l2jserver.model.world.capability;
import com.l2jserver.model.world.AbstractObject;
import com.l2jserver.util.Coordinate;
/**
* Defines an {@link AbstractObject} that can be teleported by
* {@link Teleporter} objects. Note that it is also possible to teleport
* <b>without</b> a teleporter!
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public interface Teleportable extends ObjectCapability, Positionable, Spawnable {
void teleport(Coordinate coordinate);
}

View File

@@ -0,0 +1,14 @@
package com.l2jserver.model.world.capability;
import com.l2jserver.model.world.AbstractObject;
import com.l2jserver.util.Coordinate;
/**
* Defines an {@link AbstractObject} that can teleport {@link Teleportable}
* objects.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public interface Teleporter extends ObjectCapability {
void teleport(Coordinate coord, Teleportable target);
}

View File

@@ -0,0 +1,10 @@
package com.l2jserver.model.world.player;
import com.l2jserver.model.world.Player;
import com.l2jserver.util.Coordinate;
public class PlayerTeleportEvent extends PlayerSpawnEvent {
public PlayerTeleportEvent(Player player, Coordinate coordinate) {
super(player, coordinate);
}
}

View File

@@ -0,0 +1,14 @@
package com.l2jserver.service;
import com.google.inject.AbstractModule;
import com.google.inject.Scopes;
import com.l2jserver.service.network.NettyNetworkService;
import com.l2jserver.service.network.NetworkService;
public class ServiceModule extends AbstractModule {
@Override
protected void configure() {
bind(NetworkService.class).to(NettyNetworkService.class).in(
Scopes.SINGLETON);
}
}

View File

@@ -0,0 +1,21 @@
package com.l2jserver.service.game.world;
import com.l2jserver.model.world.event.WorldEvent;
/**
* This event dispatcher notify listeners that an certain event occured in their
* objects.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public interface WorldEventDispatcher {
/**
* Notify listeners of the <tt>event</tt>. Note that not all implementation
* need to invoke listeners immediately. Dispatching <b>can</b> occur
* concurrently.
*
* @param event
* the event
*/
void dispatch(WorldEvent event);
}

View File

@@ -0,0 +1,67 @@
/*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.util;
import java.util.Random;
/**
* Blowfish keygen for GameServer client connections
*
* @author KenM
*/
public class BlowFishKeygen {
private static final int CRYPT_KEYS_SIZE = 20;
private static final byte[][] CRYPT_KEYS = new byte[CRYPT_KEYS_SIZE][16];
private static final Random random = new Random();
static {
// init the GS encryption keys on class load
for (int i = 0; i < CRYPT_KEYS_SIZE; i++) {
// randomize the 8 first bytes
for (int j = 0; j < CRYPT_KEYS[i].length; j++) {
CRYPT_KEYS[i][j] = (byte) random.nextInt(255);
}
// the last 8 bytes are static
CRYPT_KEYS[i][8] = (byte) 0xc8;
CRYPT_KEYS[i][9] = (byte) 0x27;
CRYPT_KEYS[i][10] = (byte) 0x93;
CRYPT_KEYS[i][11] = (byte) 0x01;
CRYPT_KEYS[i][12] = (byte) 0xa1;
CRYPT_KEYS[i][13] = (byte) 0x6c;
CRYPT_KEYS[i][14] = (byte) 0x31;
CRYPT_KEYS[i][15] = (byte) 0x97;
}
}
// block instantiation
private BlowFishKeygen() {
}
/**
* Returns a key from this keygen pool, the logical ownership is retained by
* this keygen.<BR>
* Thus when getting a key with interests other then read-only a copy must
* be performed.<BR>
*
* @return A key from this keygen pool.
*/
public static byte[] getRandomKey() {
return CRYPT_KEYS[random.nextInt(CRYPT_KEYS_SIZE)];
}
}

View File

@@ -0,0 +1,121 @@
package com.l2jserver.service.world;
import java.util.concurrent.atomic.AtomicBoolean;
import junit.framework.Assert;
import org.junit.Before;
import org.junit.Test;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Scopes;
import com.l2jserver.model.world.L2Character;
import com.l2jserver.model.world.Item;
import com.l2jserver.model.world.item.ItemDropEvent;
import com.l2jserver.model.world.item.ItemEvent;
import com.l2jserver.model.world.item.ItemListener;
import com.l2jserver.model.world.player.PlayerEvent;
import com.l2jserver.model.world.player.PlayerListener;
import com.l2jserver.model.world.player.PlayerSpawnEvent;
import com.l2jserver.service.BasicServiceModule;
import com.l2jserver.service.ServiceStartException;
import com.l2jserver.service.game.world.WorldEventDispatcher;
import com.l2jserver.service.game.world.WorldEventDispatcherImpl;
import com.l2jserver.service.game.world.WorldService;
import com.l2jserver.service.game.world.WorldServiceImpl;
public class WorldEventDispatcherImplTest {
private WorldService world;
private WorldEventDispatcher dispatcher;
@Before
public void tearUp() throws ServiceStartException {
Injector injector = Guice.createInjector(new BasicServiceModule(),
new AbstractModule() {
@Override
protected void configure() {
bind(WorldService.class).to(WorldServiceImpl.class).in(
Scopes.SINGLETON);
bind(WorldEventDispatcher.class).to(
WorldEventDispatcherImpl.class).in(
Scopes.SINGLETON);
}
});
world = injector.getInstance(WorldService.class);
dispatcher = injector.getInstance(WorldEventDispatcher.class);
Assert.assertNotNull(world);
Assert.assertNotNull(dispatcher);
world.start();
}
@Test
public void testListeners1() {
final L2Character character1 = new L2Character();
final L2Character character2 = new L2Character();
final Item item1 = new Item();
world.add(character1);
world.add(character2);
world.add(item1);
final AtomicBoolean bool = new AtomicBoolean();
Assert.assertFalse(bool.get());
character1.addListener(new PlayerListener() {
@Override
protected void dispatch(PlayerEvent e) {
bool.set(true);
e.getPlayer().removeListener(this);
}
});
character1.addListener(new PlayerListener() {
@Override
protected void dispatch(PlayerEvent e) {
// bool.set(true);
}
});
dispatcher.dispatch(new PlayerSpawnEvent(character1, null));
Assert.assertTrue(bool.get());
bool.set(false);
dispatcher.dispatch(new PlayerSpawnEvent(character1, null));
Assert.assertFalse(bool.get());
}
@Test
public void testListeners2() {
final L2Character character1 = new L2Character();
final L2Character character2 = new L2Character();
final Item item1 = new Item();
final Item item2 = new Item();
world.add(character1);
world.add(character2);
world.add(item1);
world.add(item2);
final AtomicBoolean bool1 = new AtomicBoolean();
final AtomicBoolean bool2 = new AtomicBoolean();
Assert.assertFalse(bool1.get());
Assert.assertFalse(bool2.get());
character1.addListener(new PlayerListener() {
@Override
public void dispatch(PlayerEvent e) {
bool1.set(true);
}
});
item1.addListener(new ItemListener() {
@Override
public void dispatch(ItemEvent e) {
bool2.set(true);
}
});
dispatcher.dispatch(new ItemDropEvent(character1, item1));
Assert.assertTrue(bool1.get());
Assert.assertTrue(bool2.get());
}
}