.
+ *
+ * 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 .
+ */
+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 Rogiel
+ */
+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;
+ }
+ }
+}
diff --git a/src/main/java/com/l2jserver/game/net/packet/client/CM_PROTOCOL_VERSION.java b/src/main/java/com/l2jserver/game/net/packet/client/CM_PROTOCOL_VERSION.java
index 044c33dee..5af43a5a3 100644
--- a/src/main/java/com/l2jserver/game/net/packet/client/CM_PROTOCOL_VERSION.java
+++ b/src/main/java/com/l2jserver/game/net/packet/client/CM_PROTOCOL_VERSION.java
@@ -24,9 +24,9 @@ import org.slf4j.LoggerFactory;
import com.google.inject.Inject;
import com.l2jserver.L2JConstant;
-import com.l2jserver.game.ProtocolVersion;
import com.l2jserver.game.net.Lineage2Connection;
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;
diff --git a/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_INFO.java b/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_INFO.java
index 042dcaa56..edd8b27c5 100644
--- a/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_INFO.java
+++ b/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_INFO.java
@@ -56,6 +56,13 @@ import com.l2jserver.util.BufferUtils;
/**
* This is an message informing the client of an given player
*
+ *
+ * (c) dddddSddddQdddddddddddddddddddddddddddddddddddddddddddddddddd
+ * ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd
+ * fdfdfdfddddSdddddcccddh[h]cdcdhhdhddddccdcccddddcdddddhhhhhhhdddd
+ * d
+ *
+ *
* @author Rogiel
*/
public class SM_CHAR_INFO extends AbstractServerPacket {
diff --git a/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_LIST.java b/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_LIST.java
index 48185b7b9..faff566d7 100644
--- a/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_LIST.java
+++ b/src/main/java/com/l2jserver/game/net/packet/server/SM_CHAR_LIST.java
@@ -16,7 +16,7 @@
*/
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.CHEST;
import static com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll.CLOAK;
diff --git a/src/main/java/com/l2jserver/game/net/packet/server/SM_KEY.java b/src/main/java/com/l2jserver/game/net/packet/server/SM_KEY.java
index 5ab2f3343..c4d0abab5 100644
--- a/src/main/java/com/l2jserver/game/net/packet/server/SM_KEY.java
+++ b/src/main/java/com/l2jserver/game/net/packet/server/SM_KEY.java
@@ -28,6 +28,10 @@ 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.
*
+ *
+ * (c) cbddcd
+ *
+ *
* @author Rogiel
*/
public class SM_KEY extends AbstractServerPacket {
diff --git a/src/main/java/com/l2jserver/service/game/ai/script/AttackAIScript.java b/src/main/java/com/l2jserver/model/world/actor/stat/ActorStats.java
similarity index 72%
rename from src/main/java/com/l2jserver/service/game/ai/script/AttackAIScript.java
rename to src/main/java/com/l2jserver/model/world/actor/stat/ActorStats.java
index 0472df10f..cce3ab7ed 100644
--- a/src/main/java/com/l2jserver/service/game/ai/script/AttackAIScript.java
+++ b/src/main/java/com/l2jserver/model/world/actor/stat/ActorStats.java
@@ -14,14 +14,12 @@
* You should have received a copy of the GNU General Public License
* along with l2jserver. If not, see .
*/
-package com.l2jserver.service.game.ai.script;
-
-import com.l2jserver.model.world.Actor;
-import com.l2jserver.service.game.ai.AIScript;
+package com.l2jserver.model.world.actor.stat;
/**
- * @author RogielRogiel
+ *
*/
-public interface AttackAIScript extends AIScript {
- void attack(Actor actor);
+public class ActorStats {
+
}
diff --git a/src/main/java/com/l2jserver/model/world/character/CharacterStats.java b/src/main/java/com/l2jserver/model/world/character/CharacterStats.java
index 6674d42ed..9b1e8c18d 100644
--- a/src/main/java/com/l2jserver/model/world/character/CharacterStats.java
+++ b/src/main/java/com/l2jserver/model/world/character/CharacterStats.java
@@ -17,6 +17,7 @@
package com.l2jserver.model.world.character;
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.character.calculator.BaseAttackAccuracyCalculator;
import com.l2jserver.model.world.character.calculator.BaseAttackEvasionCalculator;
@@ -60,7 +61,7 @@ import com.l2jserver.util.calculator.Calculator;
*
* @author Rogiel
*/
-public class CharacterStats {
+public class CharacterStats extends ActorStats {
/**
* The calculator for base maximum HP
*
@@ -244,44 +245,32 @@ public class CharacterStats {
}
// import default functions
- getCalculator(StatType.MAX_HP).importFunctions(BASE_HP_CALCULATOR);
- getCalculator(StatType.MAX_MP).importFunctions(BASE_MP_CALCULATOR);
- getCalculator(StatType.MAX_CP).importFunctions(BASE_CP_CALCULATOR);
+ add(StatType.MAX_HP, BASE_HP_CALCULATOR);
+ add(StatType.MAX_MP, BASE_MP_CALCULATOR);
+ add(StatType.MAX_CP, BASE_CP_CALCULATOR);
- getCalculator(StatType.STAT_INT).importFunctions(BASE_INT_CALCULATOR);
- getCalculator(StatType.STAT_STR).importFunctions(BASE_STR_CALCULATOR);
- getCalculator(StatType.STAT_CON).importFunctions(BASE_CON_CALCULATOR);
- getCalculator(StatType.STAT_MEN).importFunctions(BASE_MEN_CALCULATOR);
- getCalculator(StatType.STAT_DEX).importFunctions(BASE_DEX_CALCULATOR);
- getCalculator(StatType.STAT_WIT).importFunctions(BASE_WIT_CALCULATOR);
+ add(StatType.STAT_INT, BASE_INT_CALCULATOR);
+ add(StatType.STAT_STR, BASE_STR_CALCULATOR);
+ add(StatType.STAT_CON, BASE_CON_CALCULATOR);
+ add(StatType.STAT_MEN, BASE_MEN_CALCULATOR);
+ add(StatType.STAT_DEX, BASE_DEX_CALCULATOR);
+ add(StatType.STAT_WIT, BASE_WIT_CALCULATOR);
- getCalculator(StatType.RUN_SPEED).importFunctions(
- BASE_RUN_SPEED_CALCULATOR);
- getCalculator(StatType.WALK_SPEED).importFunctions(
- BASE_WALK_SPEED_CALCULATOR);
+ add(StatType.RUN_SPEED, BASE_RUN_SPEED_CALCULATOR);
+ add(StatType.WALK_SPEED, BASE_WALK_SPEED_CALCULATOR);
- getCalculator(StatType.POWER_ATTACK).importFunctions(
- BASE_PHYSICAL_ATTACK_CALCULATOR);
- getCalculator(StatType.POWER_ATTACK_SPEED).importFunctions(
- BASE_PHYSICAL_ATTACK_SPEED_CALCULATOR);
- getCalculator(StatType.CRITICAL_RATE).importFunctions(
- BASE_PHYSICAL_CRITICAL_RATE_CALCULATOR);
- getCalculator(StatType.POWER_DEFENSE).importFunctions(
- BASE_PHYSICAL_DEFENSE_CALCULATOR);
+ add(StatType.POWER_ATTACK, BASE_PHYSICAL_ATTACK_CALCULATOR);
+ add(StatType.POWER_ATTACK_SPEED, BASE_PHYSICAL_ATTACK_SPEED_CALCULATOR);
+ add(StatType.CRITICAL_RATE, BASE_PHYSICAL_CRITICAL_RATE_CALCULATOR);
+ add(StatType.POWER_DEFENSE, BASE_PHYSICAL_DEFENSE_CALCULATOR);
- getCalculator(StatType.MAGIC_ATTACK).importFunctions(
- BASE_MAGICAL_ATTACK_CALCULATOR);
- getCalculator(StatType.MAGIC_ATTACK_SPEED).importFunctions(
- BASE_MAGICAL_ATTACK_SPEED_CALCULATOR);
- getCalculator(StatType.MCRITICAL_RATE).importFunctions(
- BASE_MAGICAL_CRITICAL_RATE_CALCULATOR);
- getCalculator(StatType.MAGIC_DEFENSE).importFunctions(
- BASE_MAGICAL_DEFENSE_CALCULATOR);
+ add(StatType.MAGIC_ATTACK, BASE_MAGICAL_ATTACK_CALCULATOR);
+ add(StatType.MAGIC_ATTACK_SPEED, BASE_MAGICAL_ATTACK_SPEED_CALCULATOR);
+ add(StatType.MCRITICAL_RATE, BASE_MAGICAL_CRITICAL_RATE_CALCULATOR);
+ add(StatType.MAGIC_DEFENSE, BASE_MAGICAL_DEFENSE_CALCULATOR);
- getCalculator(StatType.ACCURACY_COMBAT).importFunctions(
- BASE_ATTACK_ACCURACY_CALCULATOR);
- getCalculator(StatType.EVASION_RATE).importFunctions(
- BASE_ATTACK_EVASION_CALCULATOR);
+ add(StatType.ACCURACY_COMBAT, BASE_ATTACK_ACCURACY_CALCULATOR);
+ add(StatType.EVASION_RATE, BASE_ATTACK_EVASION_CALCULATOR);
// TODO henna stats calculators
}
@@ -440,9 +429,13 @@ public class CharacterStats {
return (int) calc(StatType.MAX_LOAD);
}
- // public void add(StatType type, Calculator> calculator) {
- // getCalculator(type).importFunctions(calculator);
- // }
+ public void add(StatType type, Calculator calculator) {
+ getCalculator(type).importFunctions(calculator);
+ }
+
+ public void remove(StatType type, Calculator calculator) {
+ getCalculator(type).removeFunctions(calculator);
+ }
/**
* @param the
diff --git a/src/main/java/com/l2jserver/service/game/AttackServiceImpl.java b/src/main/java/com/l2jserver/service/game/AttackServiceImpl.java
index 8842223b0..0fc1d3f1c 100644
--- a/src/main/java/com/l2jserver/service/game/AttackServiceImpl.java
+++ b/src/main/java/com/l2jserver/service/game/AttackServiceImpl.java
@@ -82,7 +82,7 @@ public class AttackServiceImpl extends AbstractService implements AttackService
@Override
public AttackHit call() throws Exception {
-
+
return null;
}
}
diff --git a/src/main/java/com/l2jserver/service/game/ai/script/ProximityAIScript.java b/src/main/java/com/l2jserver/service/game/ai/script/ProximityAIScript.java
deleted file mode 100644
index ccb1687a3..000000000
--- a/src/main/java/com/l2jserver/service/game/ai/script/ProximityAIScript.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * This file is part of l2jserver .
- *
- * 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 .
- */
-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 Rogiel
- */
-public interface ProximityAIScript {
- /**
- * Invoked once another object moves in proximity or the object suddenly
- * appears.
- *
- * @param object
- * the object
- */
- void approach(PositionableObject object);
-}
diff --git a/src/main/java/com/l2jserver/service/game/ai/script/WalkingAIScript.java b/src/main/java/com/l2jserver/service/game/ai/script/WalkingAIScript.java
deleted file mode 100644
index cbb1efc3e..000000000
--- a/src/main/java/com/l2jserver/service/game/ai/script/WalkingAIScript.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * This file is part of l2jserver .
- *
- * 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 .
- */
-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 Rogiel.
+ *
+ * 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 .
+ */
+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 Rogiel
+ */
+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 query(Lineage2Connection conn);
+
+ /**
+ * The Game guard key state
+ *
+ * @author Rogiel
+ */
+ 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);
+}
diff --git a/src/main/java/com/l2jserver/service/network/gameguard/GameGuardServiceImpl.java b/src/main/java/com/l2jserver/service/network/gameguard/GameGuardServiceImpl.java
new file mode 100644
index 000000000..be117a4ba
--- /dev/null
+++ b/src/main/java/com/l2jserver/service/network/gameguard/GameGuardServiceImpl.java
@@ -0,0 +1,128 @@
+/*
+ * This file is part of l2jserver .
+ *
+ * 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 .
+ */
+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 Rogiel
+ */
+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 futures;
+ /**
+ * The {@link MessageDigest} for SHA-1.
+ *
+ * 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 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 implements
+ Future {
+ @Override
+ protected boolean set(GameGuardResponse value) {
+ // protected wrapper
+ return super.set(value);
+ }
+ }
+}