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

GameGuard service implementation

Signed-off-by: Rogiel <rogiel@rogiel.com>
This commit is contained in:
2011-05-30 13:36:01 -03:00
parent b332a10130
commit 63684a464f
22 changed files with 362 additions and 144 deletions

View File

@@ -16,7 +16,7 @@
*/ */
package com.l2jserver; package com.l2jserver;
import com.l2jserver.game.ProtocolVersion; import com.l2jserver.game.net.ProtocolVersion;
/** /**
* Constant values for this L2J compilation * Constant values for this L2J compilation

View File

@@ -21,7 +21,6 @@ import java.util.Set;
import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFuture; import org.jboss.netty.channel.ChannelFuture;
import com.l2jserver.game.ProtocolVersion;
import com.l2jserver.game.net.codec.Lineage2Decrypter; import com.l2jserver.game.net.codec.Lineage2Decrypter;
import com.l2jserver.game.net.codec.Lineage2Encrypter; import com.l2jserver.game.net.codec.Lineage2Encrypter;
import com.l2jserver.game.net.codec.Lineage2PacketReader; import com.l2jserver.game.net.codec.Lineage2PacketReader;
@@ -189,7 +188,7 @@ public class Lineage2Connection {
* *
* @param version * @param version
* @return true if version is supported by the client * @return true if version is supported by the client
* @see com.l2jserver.game.ProtocolVersion#supports(com.l2jserver.game.ProtocolVersion) * @see com.l2jserver.game.net.ProtocolVersion#supports(com.l2jserver.game.net.ProtocolVersion)
*/ */
public boolean supports(ProtocolVersion version) { public boolean supports(ProtocolVersion version) {
if (version == null) if (version == null)

View File

@@ -14,7 +14,7 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with l2jserver. If not, see <http://www.gnu.org/licenses/>. * along with l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/ */
package com.l2jserver.game; package com.l2jserver.game.net;
/** /**
* Represents the protocol version used by the client * Represents the protocol version used by the client

View File

@@ -31,7 +31,7 @@ import com.l2jserver.game.net.packet.client.CM_ADMIN_COMMAND;
import com.l2jserver.game.net.packet.client.CM_AUTH_LOGIN; import com.l2jserver.game.net.packet.client.CM_AUTH_LOGIN;
import com.l2jserver.game.net.packet.client.CM_CHAR_ACTION; 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_APPEARING;
import com.l2jserver.game.net.packet.client.CM_CHAR_ATTACK; import com.l2jserver.game.net.packet.client.CM_ATTACK;
import com.l2jserver.game.net.packet.client.CM_CHAT; import com.l2jserver.game.net.packet.client.CM_CHAT;
import com.l2jserver.game.net.packet.client.CM_CHAR_CREATE; import com.l2jserver.game.net.packet.client.CM_CHAR_CREATE;
import com.l2jserver.game.net.packet.client.CM_ACTION_USE; import com.l2jserver.game.net.packet.client.CM_ACTION_USE;
@@ -44,11 +44,11 @@ import com.l2jserver.game.net.packet.client.CM_CHAR_POSITION;
import com.l2jserver.game.net.packet.client.CM_ENTER_WORLD; import com.l2jserver.game.net.packet.client.CM_ENTER_WORLD;
import com.l2jserver.game.net.packet.client.CM_LOGOUT; 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_PROTOCOL_VERSION;
import com.l2jserver.game.net.packet.client.CM_REQUEST_ALL_FORTRESS_INFO; import com.l2jserver.game.net.packet.client.CM_EXT_REQ_ALL_FORTRESS_INFO;
import com.l2jserver.game.net.packet.client.CM_REQUEST_CHAR_TEMPLATE; import com.l2jserver.game.net.packet.client.CM_REQUEST_CHAR_TEMPLATE;
import com.l2jserver.game.net.packet.client.CM_GOTO_LOBBY; import com.l2jserver.game.net.packet.client.CM_GOTO_LOBBY;
import com.l2jserver.game.net.packet.client.CM_REQUEST_KEY_MAPPING; import com.l2jserver.game.net.packet.client.CM_EXT_REQ_KEY_MAPPING;
import com.l2jserver.game.net.packet.client.CM_REQUEST_MANOR_LIST; import com.l2jserver.game.net.packet.client.CM_EXT_REQ_MANOR_LIST;
import com.l2jserver.game.net.packet.client.CM_RESTART; import com.l2jserver.game.net.packet.client.CM_RESTART;
/** /**
@@ -139,17 +139,17 @@ public class Lineage2PacketReader extends OneToOneDecoder {
return CM_CHAR_CREATE.class; return CM_CHAR_CREATE.class;
case CM_REQUEST_CHAR_TEMPLATE.OPCODE: case CM_REQUEST_CHAR_TEMPLATE.OPCODE:
return CM_REQUEST_CHAR_TEMPLATE.class; return CM_REQUEST_CHAR_TEMPLATE.class;
case 0xd0: // COMPOSED case 0xd0: // CM_EXTENDED
final int opcode2 = buffer.readUnsignedShort(); final int opcode2 = buffer.readUnsignedShort();
switch (opcode2) { switch (opcode2) {
case CM_GOTO_LOBBY.OPCODE2: case CM_GOTO_LOBBY.OPCODE2:
return CM_GOTO_LOBBY.class; return CM_GOTO_LOBBY.class;
case CM_REQUEST_KEY_MAPPING.OPCODE2: case CM_EXT_REQ_KEY_MAPPING.OPCODE2:
return CM_REQUEST_KEY_MAPPING.class; return CM_EXT_REQ_KEY_MAPPING.class;
case CM_REQUEST_MANOR_LIST.OPCODE2: case CM_EXT_REQ_MANOR_LIST.OPCODE2:
return CM_REQUEST_MANOR_LIST.class; return CM_EXT_REQ_MANOR_LIST.class;
case CM_REQUEST_ALL_FORTRESS_INFO.OPCODE2: case CM_EXT_REQ_ALL_FORTRESS_INFO.OPCODE2:
return CM_REQUEST_ALL_FORTRESS_INFO.class; return CM_EXT_REQ_ALL_FORTRESS_INFO.class;
default: default:
logger.warn("Unknown opcode2 for 0xd0: 0x{}", logger.warn("Unknown opcode2 for 0xd0: 0x{}",
Integer.toHexString(opcode2)); Integer.toHexString(opcode2));
@@ -182,8 +182,8 @@ public class Lineage2PacketReader extends OneToOneDecoder {
return CM_ACTION_USE.class; return CM_ACTION_USE.class;
case CM_CHAR_OPEN_MAP.OPCODE: case CM_CHAR_OPEN_MAP.OPCODE:
return CM_CHAR_OPEN_MAP.class; return CM_CHAR_OPEN_MAP.class;
case CM_CHAR_ATTACK.OPCODE: case CM_ATTACK.OPCODE:
return CM_CHAR_ATTACK.class; return CM_ATTACK.class;
default: default:
logger.warn("Unknown opcode: 0x{}", Integer.toHexString(opcode)); logger.warn("Unknown opcode: 0x{}", Integer.toHexString(opcode));
break; break;

View File

@@ -41,7 +41,7 @@ import com.l2jserver.util.geometry.Coordinate;
* *
* @author <a href="http://www.rogiel.com">Rogiel</a> * @author <a href="http://www.rogiel.com">Rogiel</a>
*/ */
public class CM_CHAR_ATTACK extends AbstractClientPacket { public class CM_ATTACK extends AbstractClientPacket {
/** /**
* The packet OPCODE * The packet OPCODE
*/ */
@@ -101,7 +101,7 @@ public class CM_CHAR_ATTACK extends AbstractClientPacket {
} }
@Inject @Inject
public CM_CHAR_ATTACK(CharacterService charService, public CM_ATTACK(CharacterService charService,
ObjectIDResolver idResolver) { ObjectIDResolver idResolver) {
this.charService = charService; this.charService = charService;
this.idResolver = idResolver; this.idResolver = idResolver;

View File

@@ -27,7 +27,7 @@ import com.l2jserver.game.net.packet.server.SM_FORT_INFO;
* *
* @author <a href="http://www.rogiel.com">Rogiel</a> * @author <a href="http://www.rogiel.com">Rogiel</a>
*/ */
public class CM_REQUEST_ALL_FORTRESS_INFO extends AbstractClientPacket { public class CM_EXT_REQ_ALL_FORTRESS_INFO extends AbstractClientPacket {
/** /**
* The packet OPCODE1 * The packet OPCODE1
*/ */

View File

@@ -26,7 +26,7 @@ import com.l2jserver.game.net.packet.AbstractClientPacket;
* *
* @author <a href="http://www.rogiel.com">Rogiel</a> * @author <a href="http://www.rogiel.com">Rogiel</a>
*/ */
public class CM_REQUEST_KEY_MAPPING extends AbstractClientPacket { public class CM_EXT_REQ_KEY_MAPPING extends AbstractClientPacket {
/** /**
* The packet OPCODE1 * The packet OPCODE1
*/ */

View File

@@ -27,7 +27,7 @@ import com.l2jserver.game.net.packet.server.SM_MANOR_LIST;
* *
* @author <a href="http://www.rogiel.com">Rogiel</a> * @author <a href="http://www.rogiel.com">Rogiel</a>
*/ */
public class CM_REQUEST_MANOR_LIST extends AbstractClientPacket { public class CM_EXT_REQ_MANOR_LIST extends AbstractClientPacket {
/** /**
* The packet OPCODE1 * The packet OPCODE1
*/ */

View File

@@ -29,7 +29,7 @@ import com.l2jserver.game.net.packet.AbstractClientPacket;
* *
* @author <a href="http://www.rogiel.com">Rogiel</a> * @author <a href="http://www.rogiel.com">Rogiel</a>
*/ */
public class CM_REQUEST_SHORTCUT_REGISTRY extends AbstractClientPacket { public class CM_EXT_REQ_SHORTCUT_REGISTRY extends AbstractClientPacket {
/** /**
* The packet OPCODE1 * The packet OPCODE1
*/ */
@@ -43,7 +43,7 @@ public class CM_REQUEST_SHORTCUT_REGISTRY extends AbstractClientPacket {
* The logger * The logger
*/ */
private static final Logger log = LoggerFactory private static final Logger log = LoggerFactory
.getLogger(CM_REQUEST_SHORTCUT_REGISTRY.class); .getLogger(CM_EXT_REQ_SHORTCUT_REGISTRY.class);
/** /**
* The shortcut type * The shortcut type

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.Lineage2Connection;
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 = 0x00;
/**
* 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(Lineage2Connection 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 Lineage2Connection 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

@@ -24,9 +24,9 @@ import org.slf4j.LoggerFactory;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.l2jserver.L2JConstant; import com.l2jserver.L2JConstant;
import com.l2jserver.game.ProtocolVersion;
import com.l2jserver.game.net.Lineage2Connection; import com.l2jserver.game.net.Lineage2Connection;
import com.l2jserver.game.net.Lineage2CryptographyKey; 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.AbstractClientPacket;
import com.l2jserver.game.net.packet.server.SM_KEY; import com.l2jserver.game.net.packet.server.SM_KEY;
import com.l2jserver.service.network.keygen.BlowfishKeygenService; import com.l2jserver.service.network.keygen.BlowfishKeygenService;

View File

@@ -56,6 +56,13 @@ import com.l2jserver.util.BufferUtils;
/** /**
* This is an message informing the client of an given player * 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> * @author <a href="http://www.rogiel.com">Rogiel</a>
*/ */
public class SM_CHAR_INFO extends AbstractServerPacket { public class SM_CHAR_INFO extends AbstractServerPacket {

View File

@@ -16,7 +16,7 @@
*/ */
package com.l2jserver.game.net.packet.server; package com.l2jserver.game.net.packet.server;
import static com.l2jserver.game.ProtocolVersion.FREYA; 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.BELT;
import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.CHEST; 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.CLOAK;

View File

@@ -28,6 +28,10 @@ import com.l2jserver.game.net.packet.AbstractServerPacket;
* This packet send the encryptation keys for the client. After this message all * This packet send the encryptation keys for the client. After this message all
* communication is done with the cryptography engine enabled. * communication is done with the cryptography engine enabled.
* *
* <pre>
* (c) cbddcd
* </pre>
*
* @author <a href="http://www.rogiel.com">Rogiel</a> * @author <a href="http://www.rogiel.com">Rogiel</a>
*/ */
public class SM_KEY extends AbstractServerPacket { public class SM_KEY extends AbstractServerPacket {

View File

@@ -14,14 +14,12 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with l2jserver. If not, see <http://www.gnu.org/licenses/>. * along with l2jserver. If not, see <http://www.gnu.org/licenses/>.
*/ */
package com.l2jserver.service.game.ai.script; package com.l2jserver.model.world.actor.stat;
import com.l2jserver.model.world.Actor;
import com.l2jserver.service.game.ai.AIScript;
/** /**
* @author <a href="http://www.rogiel.com">Rogiel</a * @author <a href="http://www.rogiel.com">Rogiel</a>
*
*/ */
public interface AttackAIScript extends AIScript { public class ActorStats {
void attack(Actor actor);
} }

View File

@@ -17,6 +17,7 @@
package com.l2jserver.model.world.character; package com.l2jserver.model.world.character;
import com.l2jserver.model.world.L2Character; import com.l2jserver.model.world.L2Character;
import com.l2jserver.model.world.actor.stat.ActorStats;
import com.l2jserver.model.world.actor.stat.Stats.StatType; import com.l2jserver.model.world.actor.stat.Stats.StatType;
import com.l2jserver.model.world.character.calculator.BaseAttackAccuracyCalculator; import com.l2jserver.model.world.character.calculator.BaseAttackAccuracyCalculator;
import com.l2jserver.model.world.character.calculator.BaseAttackEvasionCalculator; import com.l2jserver.model.world.character.calculator.BaseAttackEvasionCalculator;
@@ -60,7 +61,7 @@ import com.l2jserver.util.calculator.Calculator;
* *
* @author <a href="http://www.rogiel.com">Rogiel</a> * @author <a href="http://www.rogiel.com">Rogiel</a>
*/ */
public class CharacterStats { public class CharacterStats extends ActorStats {
/** /**
* The calculator for base maximum HP * The calculator for base maximum HP
* <p> * <p>
@@ -244,44 +245,32 @@ public class CharacterStats {
} }
// import default functions // import default functions
getCalculator(StatType.MAX_HP).importFunctions(BASE_HP_CALCULATOR); add(StatType.MAX_HP, BASE_HP_CALCULATOR);
getCalculator(StatType.MAX_MP).importFunctions(BASE_MP_CALCULATOR); add(StatType.MAX_MP, BASE_MP_CALCULATOR);
getCalculator(StatType.MAX_CP).importFunctions(BASE_CP_CALCULATOR); add(StatType.MAX_CP, BASE_CP_CALCULATOR);
getCalculator(StatType.STAT_INT).importFunctions(BASE_INT_CALCULATOR); add(StatType.STAT_INT, BASE_INT_CALCULATOR);
getCalculator(StatType.STAT_STR).importFunctions(BASE_STR_CALCULATOR); add(StatType.STAT_STR, BASE_STR_CALCULATOR);
getCalculator(StatType.STAT_CON).importFunctions(BASE_CON_CALCULATOR); add(StatType.STAT_CON, BASE_CON_CALCULATOR);
getCalculator(StatType.STAT_MEN).importFunctions(BASE_MEN_CALCULATOR); add(StatType.STAT_MEN, BASE_MEN_CALCULATOR);
getCalculator(StatType.STAT_DEX).importFunctions(BASE_DEX_CALCULATOR); add(StatType.STAT_DEX, BASE_DEX_CALCULATOR);
getCalculator(StatType.STAT_WIT).importFunctions(BASE_WIT_CALCULATOR); add(StatType.STAT_WIT, BASE_WIT_CALCULATOR);
getCalculator(StatType.RUN_SPEED).importFunctions( add(StatType.RUN_SPEED, BASE_RUN_SPEED_CALCULATOR);
BASE_RUN_SPEED_CALCULATOR); add(StatType.WALK_SPEED, BASE_WALK_SPEED_CALCULATOR);
getCalculator(StatType.WALK_SPEED).importFunctions(
BASE_WALK_SPEED_CALCULATOR);
getCalculator(StatType.POWER_ATTACK).importFunctions( add(StatType.POWER_ATTACK, BASE_PHYSICAL_ATTACK_CALCULATOR);
BASE_PHYSICAL_ATTACK_CALCULATOR); add(StatType.POWER_ATTACK_SPEED, BASE_PHYSICAL_ATTACK_SPEED_CALCULATOR);
getCalculator(StatType.POWER_ATTACK_SPEED).importFunctions( add(StatType.CRITICAL_RATE, BASE_PHYSICAL_CRITICAL_RATE_CALCULATOR);
BASE_PHYSICAL_ATTACK_SPEED_CALCULATOR); add(StatType.POWER_DEFENSE, BASE_PHYSICAL_DEFENSE_CALCULATOR);
getCalculator(StatType.CRITICAL_RATE).importFunctions(
BASE_PHYSICAL_CRITICAL_RATE_CALCULATOR);
getCalculator(StatType.POWER_DEFENSE).importFunctions(
BASE_PHYSICAL_DEFENSE_CALCULATOR);
getCalculator(StatType.MAGIC_ATTACK).importFunctions( add(StatType.MAGIC_ATTACK, BASE_MAGICAL_ATTACK_CALCULATOR);
BASE_MAGICAL_ATTACK_CALCULATOR); add(StatType.MAGIC_ATTACK_SPEED, BASE_MAGICAL_ATTACK_SPEED_CALCULATOR);
getCalculator(StatType.MAGIC_ATTACK_SPEED).importFunctions( add(StatType.MCRITICAL_RATE, BASE_MAGICAL_CRITICAL_RATE_CALCULATOR);
BASE_MAGICAL_ATTACK_SPEED_CALCULATOR); add(StatType.MAGIC_DEFENSE, BASE_MAGICAL_DEFENSE_CALCULATOR);
getCalculator(StatType.MCRITICAL_RATE).importFunctions(
BASE_MAGICAL_CRITICAL_RATE_CALCULATOR);
getCalculator(StatType.MAGIC_DEFENSE).importFunctions(
BASE_MAGICAL_DEFENSE_CALCULATOR);
getCalculator(StatType.ACCURACY_COMBAT).importFunctions( add(StatType.ACCURACY_COMBAT, BASE_ATTACK_ACCURACY_CALCULATOR);
BASE_ATTACK_ACCURACY_CALCULATOR); add(StatType.EVASION_RATE, BASE_ATTACK_EVASION_CALCULATOR);
getCalculator(StatType.EVASION_RATE).importFunctions(
BASE_ATTACK_EVASION_CALCULATOR);
// TODO henna stats calculators // TODO henna stats calculators
} }
@@ -440,9 +429,13 @@ public class CharacterStats {
return (int) calc(StatType.MAX_LOAD); return (int) calc(StatType.MAX_LOAD);
} }
// public void add(StatType type, Calculator<?> calculator) { public void add(StatType type, Calculator<L2Character> calculator) {
// getCalculator(type).importFunctions(calculator); getCalculator(type).importFunctions(calculator);
// } }
public void remove(StatType type, Calculator<L2Character> calculator) {
getCalculator(type).removeFunctions(calculator);
}
/** /**
* @param the * @param the

View File

@@ -82,7 +82,7 @@ public class AttackServiceImpl extends AbstractService implements AttackService
@Override @Override
public AttackHit call() throws Exception { public AttackHit call() throws Exception {
return null; return null;
} }
} }

View File

@@ -1,35 +0,0 @@
/*
* 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.service.game.ai.script;
import com.l2jserver.model.world.PositionableObject;
/**
* This AI is used to receive notifications once another object aproaches.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public interface ProximityAIScript {
/**
* Invoked once another object moves in proximity or the object suddenly
* appears.
*
* @param object
* the object
*/
void approach(PositionableObject object);
}

View File

@@ -1,30 +0,0 @@
/*
* 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.service.game.ai.script;
import com.l2jserver.model.world.PositionableObject;
import com.l2jserver.service.game.ai.AIScript;
import com.l2jserver.util.geometry.Coordinate;
/**
* @author <a href="http://www.rogiel.com">Rogiel</a
*/
public interface WalkingAIScript extends AIScript {
void walk(Coordinate coord);
void follow(PositionableObject positionable);
}

View File

@@ -21,17 +21,16 @@ import com.google.inject.Inject;
import com.l2jserver.db.dao.ItemDAO; import com.l2jserver.db.dao.ItemDAO;
import com.l2jserver.game.net.Lineage2Connection; import com.l2jserver.game.net.Lineage2Connection;
import com.l2jserver.game.net.SystemMessage; import com.l2jserver.game.net.SystemMessage;
import com.l2jserver.game.net.packet.server.SM_CHAT; import com.l2jserver.game.net.packet.server.SM_CHAR_INFO;
import com.l2jserver.game.net.packet.server.SM_MOVE;
import com.l2jserver.game.net.packet.server.SM_CHAR_INFO_BROADCAST; import com.l2jserver.game.net.packet.server.SM_CHAR_INFO_BROADCAST;
import com.l2jserver.game.net.packet.server.SM_CHAR_INFO_EXTRA; import com.l2jserver.game.net.packet.server.SM_CHAR_INFO_EXTRA;
import com.l2jserver.game.net.packet.server.SM_CHAR_INFO;
import com.l2jserver.game.net.packet.server.SM_CHAR_INVENTORY; import com.l2jserver.game.net.packet.server.SM_CHAR_INVENTORY;
import com.l2jserver.game.net.packet.server.SM_CHAT;
import com.l2jserver.game.net.packet.server.SM_MOVE;
import com.l2jserver.game.net.packet.server.SM_MOVE_TYPE; import com.l2jserver.game.net.packet.server.SM_MOVE_TYPE;
import com.l2jserver.game.net.packet.server.SM_TARGET;
import com.l2jserver.game.net.packet.server.SM_GG_QUERY;
import com.l2jserver.game.net.packet.server.SM_NPC_INFO; import com.l2jserver.game.net.packet.server.SM_NPC_INFO;
import com.l2jserver.game.net.packet.server.SM_OBJECT_REMOVE; import com.l2jserver.game.net.packet.server.SM_OBJECT_REMOVE;
import com.l2jserver.game.net.packet.server.SM_TARGET;
import com.l2jserver.model.id.object.CharacterID; import com.l2jserver.model.id.object.CharacterID;
import com.l2jserver.model.template.NPCTemplate; import com.l2jserver.model.template.NPCTemplate;
import com.l2jserver.model.world.Actor; import com.l2jserver.model.world.Actor;
@@ -74,6 +73,7 @@ import com.l2jserver.service.game.world.filter.impl.IDFilter;
import com.l2jserver.service.game.world.filter.impl.KnownListFilter; import com.l2jserver.service.game.world.filter.impl.KnownListFilter;
import com.l2jserver.service.game.world.filter.impl.KnownListUpdateFilter; import com.l2jserver.service.game.world.filter.impl.KnownListUpdateFilter;
import com.l2jserver.service.network.NetworkService; import com.l2jserver.service.network.NetworkService;
import com.l2jserver.service.network.gameguard.GameGuardService;
import com.l2jserver.util.geometry.Coordinate; import com.l2jserver.util.geometry.Coordinate;
import com.l2jserver.util.geometry.Point3D; import com.l2jserver.util.geometry.Point3D;
@@ -110,6 +110,10 @@ public class CharacterServiceImpl extends AbstractService implements
* The {@link NPCService} * The {@link NPCService}
*/ */
private final NPCService npcService; private final NPCService npcService;
/**
* The {@link GameGuardService}
*/
private final GameGuardService ggService;
/** /**
* The {@link ItemDAO} * The {@link ItemDAO}
*/ */
@@ -124,13 +128,14 @@ public class CharacterServiceImpl extends AbstractService implements
public CharacterServiceImpl(WorldService worldService, public CharacterServiceImpl(WorldService worldService,
WorldEventDispatcher eventDispatcher, ChatService chatService, WorldEventDispatcher eventDispatcher, ChatService chatService,
NetworkService networkService, SpawnService spawnService, NetworkService networkService, SpawnService spawnService,
NPCService npcService, ItemDAO itemDao) { NPCService npcService, GameGuardService ggService, ItemDAO itemDao) {
this.worldService = worldService; this.worldService = worldService;
this.eventDispatcher = eventDispatcher; this.eventDispatcher = eventDispatcher;
this.chatService = chatService; this.chatService = chatService;
this.networkService = networkService; this.networkService = networkService;
this.spawnService = spawnService; this.spawnService = spawnService;
this.npcService = npcService; this.npcService = npcService;
this.ggService = ggService;
this.itemDao = itemDao; this.itemDao = itemDao;
} }
@@ -260,11 +265,13 @@ public class CharacterServiceImpl extends AbstractService implements
globalChatListener); globalChatListener);
chatService.getTradeChannel().addChatChannelListener(tradeChatListener); chatService.getTradeChannel().addChatChannelListener(tradeChatListener);
// query client game guard -- if key is invalid, the connection will be
// closed as soon as possible
ggService.query(conn);
// send this user information // send this user information
conn.write(new SM_CHAR_INFO(character)); conn.write(new SM_CHAR_INFO(character));
conn.write(new SM_CHAR_INFO_EXTRA(character)); conn.write(new SM_CHAR_INFO_EXTRA(character));
// TODO game guard enforcing
conn.write(new SM_GG_QUERY());
conn.write(new SM_CHAR_INVENTORY(character.getInventory())); conn.write(new SM_CHAR_INVENTORY(character.getInventory()));
conn.sendSystemMessage(SystemMessage.WELCOME_TO_LINEAGE); conn.sendSystemMessage(SystemMessage.WELCOME_TO_LINEAGE);

View File

@@ -0,0 +1,65 @@
/*
* 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.service.network.gameguard;
import java.util.concurrent.Future;
import com.l2jserver.game.net.Lineage2Connection;
/**
* This service is responsible for querying and validating GameGuard packets
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public interface GameGuardService {
/**
* Queries the client GameGuard for an response
*
* @param conn
* the lineage 2 connection
* @return an future that will be used to obtain validation status
*/
Future<GameGuardResponse> query(Lineage2Connection conn);
/**
* The Game guard key state
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public enum GameGuardResponse {
/**
* Key is valid
*/
VALID,
/**
* Key is not valid
*/
INVALID;
}
/**
* Sets the game guard key for the given connection. Future will be notified
* of the key state (valid or invalid).
*
* @param conn
* the connection
* @param key
* the key
* @return the validation state
*/
GameGuardResponse key(Lineage2Connection conn, byte[] key);
}

View File

@@ -0,0 +1,128 @@
/*
* 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.service.network.gameguard;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Map;
import java.util.concurrent.Future;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelFutureListener;
import com.google.common.util.concurrent.AbstractFuture;
import com.l2jserver.game.net.Lineage2Connection;
import com.l2jserver.game.net.packet.server.SM_GG_QUERY;
import com.l2jserver.service.AbstractService;
import com.l2jserver.service.ServiceStartException;
import com.l2jserver.service.ServiceStopException;
import com.l2jserver.util.factory.CollectionFactory;
/**
* Default implementation for {@link GameGuardService}
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class GameGuardServiceImpl extends AbstractService implements
GameGuardService {
/**
* The valid GG SHA1 response
*/
private static final byte[] VALID_KEY_SHA1 = { (byte) 0x88, 0x40, 0x1c,
(byte) 0xa7, (byte) 0x83, 0x42, (byte) 0xe9, 0x15, (byte) 0xde,
(byte) 0xc3, 0x68, (byte) 0xf6, 0x2d, 0x23, (byte) 0xf1, 0x3f,
(byte) 0xee, 0x68, 0x5b, (byte) 0xc5 };
/**
* The map containing all pending futures
*/
private Map<Lineage2Connection, GGFuture> futures;
/**
* The {@link MessageDigest} for SHA-1.
* <p>
* <b>Access must be synchronized externally.
*/
private MessageDigest digester;
@Override
protected void doStart() throws ServiceStartException {
futures = CollectionFactory.newMap();
try {
digester = MessageDigest.getInstance("SHA");
} catch (NoSuchAlgorithmException e) {
throw new ServiceStartException(e);
}
}
@Override
public Future<GameGuardResponse> query(final Lineage2Connection conn) {
conn.write(new SM_GG_QUERY()).addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future)
throws Exception {
if (future.getCause() != null) {
futures.remove(conn);
}
}
});
final GGFuture future = new GGFuture();
futures.put(conn, future);
return future;
}
@Override
public GameGuardResponse key(Lineage2Connection conn, byte[] key) {
final GGFuture future = futures.remove(conn);
final boolean validated = validate(conn, key);
final GameGuardResponse response = (validated ? GameGuardResponse.VALID
: GameGuardResponse.INVALID);
if (future != null)
future.set(response);
return response;
}
/**
* Creates a SHA1 sum of the key and checks is validity.
*
* @param conn
* the connection
* @param key
* the key
* @return true if key is valid
*/
private boolean validate(Lineage2Connection conn, byte[] key) {
synchronized (digester) {
return Arrays.equals(VALID_KEY_SHA1, digester.digest(key));
}
}
@Override
protected void doStop() throws ServiceStopException {
futures = null;
digester = null;
}
private class GGFuture extends AbstractFuture<GameGuardResponse> implements
Future<GameGuardResponse> {
@Override
protected boolean set(GameGuardResponse value) {
// protected wrapper
return super.set(value);
}
}
}