1
0
mirror of https://github.com/Rogiel/l2jserver2 synced 2025-12-10 09:22:49 +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

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

View File

@@ -1,27 +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.Actor;
import com.l2jserver.service.game.ai.AIScript;
/**
* @author <a href="http://www.rogiel.com">Rogiel</a
*/
public interface AttackAIScript extends AIScript {
void attack(Actor actor);
}

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.game.net.Lineage2Connection;
import com.l2jserver.game.net.SystemMessage;
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_CHAR_INFO;
import com.l2jserver.game.net.packet.server.SM_CHAR_INFO_BROADCAST;
import com.l2jserver.game.net.packet.server.SM_CHAR_INFO_EXTRA;
import com.l2jserver.game.net.packet.server.SM_CHAR_INFO;
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_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_OBJECT_REMOVE;
import com.l2jserver.game.net.packet.server.SM_TARGET;
import com.l2jserver.model.id.object.CharacterID;
import com.l2jserver.model.template.NPCTemplate;
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.KnownListUpdateFilter;
import com.l2jserver.service.network.NetworkService;
import com.l2jserver.service.network.gameguard.GameGuardService;
import com.l2jserver.util.geometry.Coordinate;
import com.l2jserver.util.geometry.Point3D;
@@ -110,6 +110,10 @@ public class CharacterServiceImpl extends AbstractService implements
* The {@link NPCService}
*/
private final NPCService npcService;
/**
* The {@link GameGuardService}
*/
private final GameGuardService ggService;
/**
* The {@link ItemDAO}
*/
@@ -124,13 +128,14 @@ public class CharacterServiceImpl extends AbstractService implements
public CharacterServiceImpl(WorldService worldService,
WorldEventDispatcher eventDispatcher, ChatService chatService,
NetworkService networkService, SpawnService spawnService,
NPCService npcService, ItemDAO itemDao) {
NPCService npcService, GameGuardService ggService, ItemDAO itemDao) {
this.worldService = worldService;
this.eventDispatcher = eventDispatcher;
this.chatService = chatService;
this.networkService = networkService;
this.spawnService = spawnService;
this.npcService = npcService;
this.ggService = ggService;
this.itemDao = itemDao;
}
@@ -260,11 +265,13 @@ public class CharacterServiceImpl extends AbstractService implements
globalChatListener);
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
conn.write(new SM_CHAR_INFO(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.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);
}
}
}