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

Inventory open implementation, Html updates, Pathing generator,

Signed-off-by: Rogiel <rogiel@rogiel.com>
This commit is contained in:
2011-05-19 23:42:45 -03:00
parent 1de8662be6
commit 9b4fe02ee4
49 changed files with 908 additions and 166 deletions

2
data/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
/cache
/pathing.db

View File

@@ -118,14 +118,7 @@
<artifactId>htmlparser</artifactId>
<version>2.1</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.htmlparser</groupId>
<artifactId>sitecapturer</artifactId>
<version>2.1</version>
<type>jar</type>
<scope>compile</scope>
<scope>runtime</scope>
</dependency>
</dependencies>

View File

@@ -33,11 +33,14 @@ import com.l2jserver.model.template.ItemTemplate;
import com.l2jserver.model.world.Item;
import com.l2jserver.model.world.L2Character;
import com.l2jserver.model.world.character.CharacterInventory;
import com.l2jserver.model.world.character.CharacterInventory.InventoryLocation;
import com.l2jserver.model.world.character.CharacterInventory.InventoryPaperdoll;
import com.l2jserver.service.database.DatabaseService;
import com.l2jserver.service.database.MySQLDatabaseService.CachedMapper;
import com.l2jserver.service.database.MySQLDatabaseService.Mapper;
import com.l2jserver.service.database.MySQLDatabaseService.SelectListQuery;
import com.l2jserver.service.database.MySQLDatabaseService.SelectSingleQuery;
import com.l2jserver.util.dimensional.Coordinate;
/**
* {@link ItemDAO} implementation for MySQL5
@@ -67,6 +70,13 @@ public class MySQL5ItemDAO extends AbstractMySQL5DAO<Item> implements ItemDAO {
public static final String TEMPLATE_ID = "template_id";
public static final String CHAR_ID = MySQL5CharacterDAO.CHAR_ID;
public static final String LOCATION = "location";
public static final String PAPERDOLL = "paperdoll";
public static final String COUNT = "count";
public static final String COORD_X = "coord_x";
public static final String COORD_Y = "coord_y";
public static final String COORD_Z = "coord_z";
@Inject
public MySQL5ItemDAO(DatabaseService database,
final ItemIDProvider idFactory,
@@ -95,7 +105,21 @@ public class MySQL5ItemDAO extends AbstractMySQL5DAO<Item> implements ItemDAO {
final Item item = template.create();
item.setID(id);
item.setOwnerID(charIdFactory.createID(rs.getInt(CHAR_ID)));
if (rs.getObject(CHAR_ID) != null)
item.setOwnerID(charIdFactory.createID(rs.getInt(CHAR_ID)));
if (rs.getObject(LOCATION) != null)
item.setLocation(InventoryLocation.valueOf(rs
.getString(LOCATION)));
if (rs.getObject(PAPERDOLL) != null)
item.setPaperdoll(InventoryPaperdoll.valueOf(rs
.getString(PAPERDOLL)));
item.setCount(rs.getInt(COUNT));
if (rs.getObject(COORD_X) != null && rs.getObject(COORD_Y) != null
&& rs.getObject(COORD_Z) != null)
item.setPosition(Coordinate.fromXYZ(rs.getInt(COORD_X),
rs.getInt(COORD_Y), rs.getInt(COORD_Z)));
return item;
}
@@ -107,7 +131,7 @@ public class MySQL5ItemDAO extends AbstractMySQL5DAO<Item> implements ItemDAO {
private final Mapper<ItemID> idMapper = new Mapper<ItemID>() {
@Override
public ItemID map(ResultSet rs) throws SQLException {
return idFactory.createID(rs.getInt(CHAR_ID));
return idFactory.createID(rs.getInt(ITEM_ID));
}
};
@@ -161,7 +185,7 @@ public class MySQL5ItemDAO extends AbstractMySQL5DAO<Item> implements ItemDAO {
return database.query(new SelectListQuery<ItemID>() {
@Override
protected String query() {
return "SELECT `" + CHAR_ID + "` FROM `" + TABLE + "`";
return "SELECT `" + ITEM_ID + "` FROM `" + TABLE + "`";
}
@Override

View File

@@ -23,7 +23,7 @@ import com.l2jserver.game.ProtocolVersion;
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class L2JConstants {
public class L2JConstant {
/**
* Indicate the supported protocol for this compilation.
* <p>

View File

@@ -17,19 +17,25 @@
package com.l2jserver;
import com.google.inject.Injector;
import com.l2jserver.db.dao.ItemDAO;
import com.l2jserver.model.id.ObjectID;
import com.l2jserver.model.id.object.provider.NPCIDProvider;
import com.l2jserver.model.id.object.provider.ObjectIDResolver;
import com.l2jserver.model.id.template.NPCTemplateID;
import com.l2jserver.model.id.template.provider.NPCTemplateIDProvider;
import com.l2jserver.model.world.L2Character;
import com.l2jserver.model.world.NPC;
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.CharacterService;
import com.l2jserver.service.game.SpawnService;
import com.l2jserver.service.game.chat.ChatService;
import com.l2jserver.service.game.pathing.PathingService;
import com.l2jserver.service.game.scripting.ScriptingService;
import com.l2jserver.service.game.template.TemplateService;
import com.l2jserver.service.game.world.id.WorldIDService;
import com.l2jserver.service.game.world.WorldIDService;
import com.l2jserver.service.network.NetworkService;
import com.l2jserver.service.network.keygen.BlowfishKeygenService;
import com.l2jserver.util.dimensional.Point;
@@ -55,6 +61,9 @@ public class L2JGameServerMain {
serviceManager.start(ChatService.class);
serviceManager.start(CharacterService.class);
serviceManager.start(PathingService.class);
serviceManager.start(BlowfishKeygenService.class);
serviceManager.start(NetworkService.class);
@@ -86,5 +95,16 @@ public class L2JGameServerMain {
npc.setPoint(Point.fromXYZ(-71301, 258259, -3134));
spawnService.spawn(npc, null);
final ObjectIDResolver resolver = injector
.getInstance(ObjectIDResolver.class);
final ObjectID<L2Character> cid = resolver.resolve(268437456);
L2Character c = cid.getObject();
System.out
.println(injector.getInstance(ItemDAO.class).loadInventory(c));
System.out.println(injector.getInstance(ObjectIDResolver.class)
.resolve(268635457).getObject());
}
}

View File

@@ -31,6 +31,7 @@ import com.l2jserver.game.net.packet.client.AuthLoginPacket;
import com.l2jserver.game.net.packet.client.CharacterActionPacket;
import com.l2jserver.game.net.packet.client.CharacterChatMessagePacket;
import com.l2jserver.game.net.packet.client.CharacterCreatePacket;
import com.l2jserver.game.net.packet.client.CharacterRequestInventoryPacket;
import com.l2jserver.game.net.packet.client.CharacterRequestMovePacket;
import com.l2jserver.game.net.packet.client.CharacterSelectPacket;
import com.l2jserver.game.net.packet.client.CharacterValidatePositionPacket;
@@ -163,6 +164,8 @@ public class Lineage2PacketReader extends OneToOneDecoder {
return EnterWorld.class;
case CharacterActionPacket.OPCODE:
return CharacterActionPacket.class;
case CharacterRequestInventoryPacket.OPCODE:
return CharacterRequestInventoryPacket.class;
default:
logger.warn("Unknown opcode: 0x{}", Integer.toHexString(opcode));
break;

View File

@@ -17,8 +17,6 @@
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;
@@ -27,7 +25,6 @@ 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.world.WorldService;
import com.l2jserver.util.dimensional.Coordinate;
/**
@@ -85,7 +82,6 @@ public class CharacterActionPacket extends AbstractClientPacket {
@Override
public void process(final Lineage2Connection conn) {
// since this is an erasure type, this is safe.
System.out.println(objectId);
final ObjectID<NPC> id = idResolver.resolve(objectId);
if (!(id instanceof NPCID)) {
System.out.println("Incorrect type: " + id);

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.Lineage2Connection;
import com.l2jserver.game.net.packet.AbstractClientPacket;
import com.l2jserver.game.net.packet.server.CharacterInventoryPacket;
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 CharacterRequestInventoryPacket extends AbstractClientPacket {
/**
* The packet OPCODE
*/
public static final int OPCODE = 0x14;
@Override
public void read(Lineage2Connection conn, ChannelBuffer buffer) {
}
@Override
public void process(final Lineage2Connection conn) {
final L2Character character = conn.getCharacter();
conn.write(new CharacterInventoryPacket(character.getInventory()));
}
}

View File

@@ -21,8 +21,7 @@ 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.model.world.character.event.CharacterMoveEvent;
import com.l2jserver.service.game.world.event.WorldEventDispatcher;
import com.l2jserver.service.game.CharacterService;
import com.l2jserver.util.dimensional.Point;
/**
@@ -37,16 +36,16 @@ public class CharacterValidatePositionPacket extends AbstractClientPacket {
public static final int OPCODE = 0x59;
/**
* The World Event Dispatcher
* The {@link CharacterService}
*/
private final WorldEventDispatcher eventDispatcher;
private final CharacterService charService;
private Point point;
private int extra; // vehicle id
@Inject
public CharacterValidatePositionPacket(WorldEventDispatcher eventDispatcher) {
this.eventDispatcher = eventDispatcher;
public CharacterValidatePositionPacket(CharacterService charService) {
this.charService = charService;
}
@Override
@@ -58,8 +57,6 @@ public class CharacterValidatePositionPacket extends AbstractClientPacket {
@Override
public void process(final Lineage2Connection conn) {
conn.getCharacter().setPoint(point);
eventDispatcher.dispatch(new CharacterMoveEvent(conn.getCharacter(),
point));
charService.receivedValidation(conn.getCharacter(), point);
}
}

View File

@@ -23,7 +23,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.inject.Inject;
import com.l2jserver.L2JConstants;
import com.l2jserver.L2JConstant;
import com.l2jserver.game.ProtocolVersion;
import com.l2jserver.game.net.Lineage2Connection;
import com.l2jserver.game.net.Lineage2CryptographyKey;
@@ -87,9 +87,9 @@ public class ProtocolVersionPacket extends AbstractClientPacket {
log.debug("Client protocol version: {}", version);
conn.setVersion(version);
if (L2JConstants.SUPPORTED_PROTOCOL != version) {
if (L2JConstant.SUPPORTED_PROTOCOL != version) {
log.info("Incorrect protocol version: {0}. Only {1} is supported.",
version, L2JConstants.SUPPORTED_PROTOCOL);
version, L2JConstant.SUPPORTED_PROTOCOL);
// notify wrong protocol and close connection
conn.write(new KeyPacket(inKey, false)).addListener(
new ChannelFutureListener() {

View File

@@ -42,26 +42,28 @@ public class ActorMovementPacket extends AbstractServerPacket {
*/
private final Actor actor;
/**
* The source coordinate
* The source target
*/
private Coordinate source;
private Coordinate target;
public ActorMovementPacket(Actor actor, Coordinate source) {
public ActorMovementPacket(Actor actor, Coordinate target) {
super(OPCODE);
this.actor = actor;
this.source = source;
this.target = target;
}
@Override
public void write(Lineage2Connection 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());
buffer.writeInt(source.getX());
buffer.writeInt(source.getY());
buffer.writeInt(source.getZ());
}
}

View File

@@ -281,7 +281,7 @@ public class CharacterInformationPacket extends AbstractServerPacket {
buffer.writeInt(0x01); // special effects? circles around player...
buffer.writeInt(200); // max cp
buffer.writeInt(200); // cur cp
buffer.writeByte(127); // is mount or is airshilhelp = 0; otherwise
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

View File

@@ -51,26 +51,29 @@ public class CharacterInventoryPacket extends AbstractServerPacket {
@Override
public void write(Lineage2Connection conn, ChannelBuffer buffer) {
buffer.writeByte((showWindow ? 0x01 : 0x00));
buffer.writeInt(inventory.getItemCount()); // item count
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
if (item.getLocation() == InventoryLocation.PAPERDOLL) {
buffer.writeInt(item.getPaperdoll().id); // loc slot
} else {
buffer.writeInt(0x00); // loc slot
}
buffer.writeInt(slot); // loc slot
buffer.writeLong(item.getCount()); // count
buffer.writeShort(0x00); // item type2
buffer.writeShort(0x00); // item type3
if (item.getLocation() == InventoryLocation.PAPERDOLL) {
buffer.writeShort(0x01); // equiped?
} else {
buffer.writeShort(0x00); // equiped?
}
buffer.writeInt(0x00); // body part
buffer.writeShort(0x00); // enchant level
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
@@ -85,6 +88,8 @@ public class CharacterInventoryPacket extends AbstractServerPacket {
buffer.writeShort(0x00);
buffer.writeShort(0x00);
buffer.writeShort(0x00);
slot++;
}
// TODO inventory block
// buffer.writeShort(_inventory.getBlockItems().length);

View File

@@ -23,6 +23,7 @@ import com.l2jserver.game.net.Lineage2Connection;
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.
@@ -36,18 +37,24 @@ public class NPCHtmlMessagePacket extends AbstractServerPacket {
public static final int OPCODE = 0x19;
private final NPC npc;
private final Html html;
private final String html;
public NPCHtmlMessagePacket(NPC npc, Html html) {
super(OPCODE);
this.npc = npc;
this.html = html;
this.html = html.toHtml();
}
public NPCHtmlMessagePacket(NPC npc, HtmlTemplate markup) {
super(OPCODE);
this.npc = npc;
this.html = markup.toHtmlString();
}
@Override
public void write(Lineage2Connection conn, ChannelBuffer buffer) {
buffer.writeInt(npc.getID().getID());
BufferUtils.writeString(buffer, html.toHtml());
BufferUtils.writeString(buffer, html);
buffer.writeInt(0x00); // item id
}
}

View File

@@ -21,7 +21,7 @@ import com.google.inject.assistedinject.Assisted;
import com.l2jserver.model.id.object.CharacterID;
import com.l2jserver.model.id.object.allocator.IDAllocator;
import com.l2jserver.model.id.provider.IDProvider;
import com.l2jserver.service.game.world.id.WorldIDService;
import com.l2jserver.service.game.world.WorldIDService;
/**
* {@link IDProvider} for {@link CharacterID}.

View File

@@ -21,7 +21,7 @@ import com.google.inject.assistedinject.Assisted;
import com.l2jserver.model.id.object.ClanID;
import com.l2jserver.model.id.object.allocator.IDAllocator;
import com.l2jserver.model.id.provider.IDProvider;
import com.l2jserver.service.game.world.id.WorldIDService;
import com.l2jserver.service.game.world.WorldIDService;
/**
* {@link IDProvider} for {@link ClanID}.

View File

@@ -21,7 +21,7 @@ import com.google.inject.assistedinject.Assisted;
import com.l2jserver.model.id.object.ItemID;
import com.l2jserver.model.id.object.allocator.IDAllocator;
import com.l2jserver.model.id.provider.IDProvider;
import com.l2jserver.service.game.world.id.WorldIDService;
import com.l2jserver.service.game.world.WorldIDService;
/**
* {@link IDProvider} for {@link ItemID}.

View File

@@ -21,7 +21,7 @@ import com.google.inject.assistedinject.Assisted;
import com.l2jserver.model.id.object.NPCID;
import com.l2jserver.model.id.object.allocator.IDAllocator;
import com.l2jserver.model.id.provider.IDProvider;
import com.l2jserver.service.game.world.id.WorldIDService;
import com.l2jserver.service.game.world.WorldIDService;
/**
* {@link IDProvider} for {@link NPCID}.

View File

@@ -18,7 +18,7 @@ package com.l2jserver.model.id.object.provider;
import com.google.inject.Inject;
import com.l2jserver.model.id.ObjectID;
import com.l2jserver.service.game.world.id.WorldIDService;
import com.l2jserver.service.game.world.WorldIDService;
/**
* <h1>THIS PROVIDER IS READ ONLY!</h1>

View File

@@ -21,7 +21,7 @@ import com.google.inject.assistedinject.Assisted;
import com.l2jserver.model.id.object.PetID;
import com.l2jserver.model.id.object.allocator.IDAllocator;
import com.l2jserver.model.id.provider.IDProvider;
import com.l2jserver.service.game.world.id.WorldIDService;
import com.l2jserver.service.game.world.WorldIDService;
/**
* {@link IDProvider} for {@link PetID}.

View File

@@ -30,8 +30,7 @@ import com.l2jserver.model.world.capability.Actor;
import com.l2jserver.service.game.CharacterService;
import com.l2jserver.service.network.NetworkService;
import com.l2jserver.util.calculator.Calculator;
import com.l2jserver.util.html.markup.Markup;
import com.l2jserver.util.html.markup.Markup.Builder;
import com.l2jserver.util.html.markup.HtmlTemplate;
import com.l2jserver.util.html.markup.MarkupTag;
/**
@@ -112,14 +111,16 @@ public abstract class NPCTemplate extends ActorTemplate<NPC> {
charService.target(character, npc);
// generate not implemented message
final Markup markup = new Markup(name + " - Notice", new Builder() {
final HtmlTemplate template = new HtmlTemplate(name) {
@Override
public void build(MarkupTag body) {
body.text("This NPC is not yet implemented!");
body.text("The NPC ${name} is not yet implemented!", "ff0000")
.p();
body.addLink("Click me!", "test");
}
});
conn.write(new NPCHtmlMessagePacket(npc, markup.build()));
};
template.register("name", name);
conn.write(new NPCHtmlMessagePacket(npc, template));
}
/**

View File

@@ -73,7 +73,8 @@ public class CharacterInventory implements Iterable<Item> {
* the items to be added
*/
public void load(List<Item> items) {
items.addAll(items);
this.items.clear();
this.items.addAll(items);
}
/**

View File

@@ -31,16 +31,18 @@ import com.l2jserver.service.game.SpawnService;
import com.l2jserver.service.game.SpawnServiceImpl;
import com.l2jserver.service.game.chat.ChatService;
import com.l2jserver.service.game.chat.SimpleChatService;
import com.l2jserver.service.game.pathing.MapperPathingService;
import com.l2jserver.service.game.pathing.PathingService;
import com.l2jserver.service.game.scripting.ScriptingService;
import com.l2jserver.service.game.scripting.ScriptingServiceImpl;
import com.l2jserver.service.game.template.ScriptTemplateService;
import com.l2jserver.service.game.template.TemplateService;
import com.l2jserver.service.game.world.CachedWorldIDService;
import com.l2jserver.service.game.world.WorldIDService;
import com.l2jserver.service.game.world.WorldService;
import com.l2jserver.service.game.world.WorldServiceImpl;
import com.l2jserver.service.game.world.event.WorldEventDispatcher;
import com.l2jserver.service.game.world.event.WorldEventDispatcherImpl;
import com.l2jserver.service.game.world.id.CachedWorldIDService;
import com.l2jserver.service.game.world.id.WorldIDService;
import com.l2jserver.service.logging.Log4JLoggingService;
import com.l2jserver.service.logging.LoggingService;
import com.l2jserver.service.network.NettyNetworkService;
@@ -67,6 +69,9 @@ public class ServiceModule extends AbstractModule {
bind(WorldIDService.class).to(CachedWorldIDService.class).in(
Scopes.SINGLETON);
bind(PathingService.class).to(MapperPathingService.class).in(
Scopes.SINGLETON);
bind(BlowfishKeygenService.class).to(SecureBlowfishKeygenService.class)
.in(Scopes.SINGLETON);
bind(NetworkService.class).to(NettyNetworkService.class).in(

View File

@@ -25,6 +25,8 @@ import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;
import net.sf.ehcache.config.CacheConfiguration;
import net.sf.ehcache.config.Configuration;
import net.sf.ehcache.config.DiskStoreConfiguration;
import net.sf.ehcache.store.MemoryStoreEvictionPolicy;
import com.l2jserver.service.AbstractService;
@@ -48,7 +50,8 @@ public class EhCacheService extends AbstractService implements CacheService {
@Override
protected void doStart() throws ServiceStartException {
manager = new CacheManager();
manager = new CacheManager(new Configuration().updateCheck(false)
.diskStore(new DiskStoreConfiguration().path("data/cache")));
interfaceCache = createCache("interface-cache");
}

View File

@@ -122,8 +122,7 @@ public class MySQLDatabaseService extends AbstractService implements
objectCache = new Cache(new CacheConfiguration("database-service",
IDAllocator.ALLOCABLE_IDS)
.memoryStoreEvictionPolicy(MemoryStoreEvictionPolicy.LRU)
.overflowToDisk(true).eternal(false).timeToLiveSeconds(60)
.timeToIdleSeconds(30).diskPersistent(false)
.overflowToDisk(true).eternal(true).diskPersistent(false)
.diskExpiryThreadIntervalSeconds(0));
cacheService.register(objectCache);
}

View File

@@ -20,6 +20,7 @@ import com.l2jserver.model.world.L2Character;
import com.l2jserver.model.world.capability.Actor;
import com.l2jserver.service.Service;
import com.l2jserver.util.dimensional.Coordinate;
import com.l2jserver.util.dimensional.Point;
/**
* This service manages {@link L2Character} instances
@@ -73,6 +74,26 @@ public interface CharacterService extends Service {
*/
void move(L2Character character, Coordinate coordinate);
/**
* Validates the position of an character
*
* @param character
* the character
* @param point
* the validated point
*/
void validate(L2Character character, Point point);
/**
* Called when received the validation of the position of an character
*
* @param character
* the character
* @param point
* the validated point
*/
void receivedValidation(L2Character character, Point point);
/**
* Set the character to walking mode
*

View File

@@ -17,6 +17,7 @@
package com.l2jserver.service.game;
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.ActionFailedPacket;
@@ -45,7 +46,6 @@ import com.l2jserver.model.world.character.event.CharacterTargetSelectedEvent;
import com.l2jserver.model.world.npc.event.NPCSpawnEvent;
import com.l2jserver.service.AbstractService;
import com.l2jserver.service.AbstractService.Depends;
import com.l2jserver.service.game.ai.AIService;
import com.l2jserver.service.game.chat.ChatMessageDestination;
import com.l2jserver.service.game.chat.ChatService;
import com.l2jserver.service.game.chat.channel.ChatChannel;
@@ -58,6 +58,7 @@ import com.l2jserver.service.game.world.event.WorldListener;
import com.l2jserver.service.game.world.filter.impl.KnownListFilter;
import com.l2jserver.service.network.NetworkService;
import com.l2jserver.util.dimensional.Coordinate;
import com.l2jserver.util.dimensional.Point;
/**
* Default implementation for {@link CharacterService}.
@@ -65,7 +66,7 @@ import com.l2jserver.util.dimensional.Coordinate;
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
@Depends({ WorldService.class, ChatService.class, NetworkService.class,
SpawnService.class, AIService.class })
SpawnService.class })
public class CharacterServiceImpl extends AbstractService implements
CharacterService {
/**
@@ -88,6 +89,10 @@ public class CharacterServiceImpl extends AbstractService implements
* The {@link SpawnService}
*/
private final SpawnService spawnService;
/**
* The {@link ItemDAO}
*/
private final ItemDAO itemDao;
// /**
// * The {@link AIService}
@@ -97,12 +102,14 @@ public class CharacterServiceImpl extends AbstractService implements
@Inject
public CharacterServiceImpl(WorldService worldService,
WorldEventDispatcher eventDispatcher, ChatService chatService,
NetworkService networkService, SpawnService spawnService) {
NetworkService networkService, SpawnService spawnService,
ItemDAO itemDao) {
this.worldService = worldService;
this.eventDispatcher = eventDispatcher;
this.chatService = chatService;
this.networkService = networkService;
this.spawnService = spawnService;
this.itemDao = itemDao;
}
@Override
@@ -115,6 +122,8 @@ public class CharacterServiceImpl extends AbstractService implements
// character is already in the world!
return;
itemDao.loadInventory(character);
// chat listener
final ChatChannelListener globalChatListener = new ChatChannelListener() {
@Override
@@ -221,10 +230,11 @@ public class CharacterServiceImpl extends AbstractService implements
// aiService.walk(character, coordinate);
final Coordinate source = character.getPosition();
character.setPosition(coordinate);
conn.write(new ActorMovementPacket(character, source));
// we don't set the character coordinate yet, this will be done by
// validate coordinate
conn.write(new ActorMovementPacket(character, coordinate));
// we don't dispatch events here, they will be dispatched by
// CharacterValidatePositionPacket packets at fixed time intervals.
// receivedValidation at fixed time intervals.
}
@Override
@@ -273,6 +283,17 @@ public class CharacterServiceImpl extends AbstractService implements
}
}
@Override
public void validate(L2Character character, Point point) {
// TODO implement position validation
}
@Override
public void receivedValidation(L2Character character, Point point) {
character.setPoint(point);
eventDispatcher.dispatch(new CharacterMoveEvent(character, point));
}
@Override
public void walk(L2Character character) {
final CharacterID id = character.getID();

View File

@@ -0,0 +1,144 @@
/*
* 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.pathing;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import javolution.io.Struct;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.inject.Inject;
import com.l2jserver.model.world.character.event.CharacterMoveEvent;
import com.l2jserver.service.AbstractService;
import com.l2jserver.service.AbstractService.Depends;
import com.l2jserver.service.ServiceStartException;
import com.l2jserver.service.ServiceStopException;
import com.l2jserver.service.game.CharacterService;
import com.l2jserver.service.game.world.WorldService;
import com.l2jserver.service.game.world.event.TypedWorldListener;
import com.l2jserver.service.game.world.event.WorldEventDispatcher;
import com.l2jserver.util.dimensional.Coordinate;
import com.l2jserver.util.dimensional.Point;
/**
* <h1>This implementation does not validate pathing!</h1>
* <p>
* This service does not handle pathing yet, instead in monitors client packets
* that send a location validation. With those packets, a database will be
* generated will all valid points in terrain. Later on, an system that allows
* uploading this data will be implemented and allowing the pathing data to be
* shared across all servers.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
@Depends({ CharacterService.class, WorldService.class })
public class MapperPathingService extends AbstractService implements
PathingService {
/**
* The database file for the pathing engine
*/
private static final File file = new File("data/pathing.db");
/**
* The logger
*/
private final Logger log = LoggerFactory.getLogger(this.getClass());
/**
* The {@link WorldService} event dispatcher
*/
private final WorldEventDispatcher eventDispatcher;
/**
* The database channel, will reamain open until service is stopped.
*/
private FileChannel channel;
/**
* Creates a new instance
*
* @param eventDispatcher
* the world event dispatcher
*/
@Inject
public MapperPathingService(WorldEventDispatcher eventDispatcher) {
this.eventDispatcher = eventDispatcher;
}
@Override
protected void doStart() throws ServiceStartException {
try {
this.channel = new FileOutputStream(file).getChannel();
} catch (FileNotFoundException e) {
throw new ServiceStartException(
"Could not open pathing database file", e);
}
eventDispatcher.addListener(new TypedWorldListener<CharacterMoveEvent>(
CharacterMoveEvent.class) {
@Override
protected boolean dispatch(CharacterMoveEvent e) {
final Point point = e.getPoint();
final CoordinateStruct struct = CoordinateStruct
.fromCoordinate(point.getCoordinate());
try {
channel.write(struct.getByteBuffer());
} catch (IOException e1) {
log.warn("Error writing pathing file!", e1);
}
return true;
}
});
}
@Override
protected void doStop() throws ServiceStopException {
try {
this.channel.close();
} catch (IOException e) {
throw new ServiceStopException(
"Could not close the pathing database file", e);
} finally {
this.channel = null;
}
}
/**
* This is an Javolution {@link Struct} that represents a set of coordinate
* stored in the database file
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public static class CoordinateStruct extends Struct {
public final Signed32 x = new Signed32();
public final Signed32 y = new Signed32();
public final Signed32 z = new Signed32();
public static CoordinateStruct fromCoordinate(Coordinate coordinate) {
final CoordinateStruct struct = new CoordinateStruct();
struct.x.set(coordinate.getX());
struct.y.set(coordinate.getY());
struct.z.set(coordinate.getZ());
return struct;
}
}
}

View File

@@ -0,0 +1,28 @@
/*
* 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.pathing;
import com.l2jserver.service.Service;
/**
* This service handles the pathing.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public interface PathingService extends Service {
}

View File

@@ -14,7 +14,7 @@
* 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.world.id;
package com.l2jserver.service.game.world;
import java.util.Collection;
@@ -25,6 +25,7 @@ import net.sf.ehcache.store.MemoryStoreEvictionPolicy;
import com.google.inject.Inject;
import com.l2jserver.db.dao.CharacterDAO;
import com.l2jserver.db.dao.ItemDAO;
import com.l2jserver.model.id.ID;
import com.l2jserver.model.id.ObjectID;
import com.l2jserver.model.id.object.allocator.IDAllocator;
@@ -58,18 +59,28 @@ public class CachedWorldIDService extends AbstractService implements
* The {@link CharacterDAO}
*/
private final CharacterDAO characterDao;
/**
* The {@link ItemDAO}
*/
private final ItemDAO itemDao;
/**
* The ID cache
*/
private Cache cache;
/**
* The loaded state
*/
private boolean loaded = false;
@Inject
public CachedWorldIDService(CacheService cacheService,
IDAllocator allocator, CharacterDAO characterDao) {
IDAllocator allocator, CharacterDAO characterDao, ItemDAO itemDao) {
this.cacheService = cacheService;
this.allocator = allocator;
this.characterDao = characterDao;
this.itemDao = itemDao;
}
@Override
@@ -82,9 +93,13 @@ public class CachedWorldIDService extends AbstractService implements
.timeToIdleSeconds(30).diskPersistent(false)
.diskExpiryThreadIntervalSeconds(0));
cacheService.register(cache);
}
// load all ids
@Override
public void load() {
load(characterDao.listIDs());
load(itemDao.listIDs());
loaded = true;
}
/**
@@ -103,6 +118,11 @@ public class CachedWorldIDService extends AbstractService implements
@Override
@SuppressWarnings("unchecked")
public <I extends ObjectID<?>> I resolve(int id) {
if (!loaded) {
// ignore resolving before all IDs are loaded
return null;
}
final Element element = cache.get(id);
if (element == null)
return null;
@@ -111,9 +131,8 @@ public class CachedWorldIDService extends AbstractService implements
@Override
public <I extends ObjectID<?>> void add(I id) {
if(id == null)
if (id == null)
return;
System.out.println("Registering ID: "+id);
cache.put(new Element(id.getID(), id));
}

View File

@@ -14,7 +14,7 @@
* 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.world.id;
package com.l2jserver.service.game.world;
import com.l2jserver.model.id.ObjectID;
import com.l2jserver.model.id.object.allocator.IDAllocator;
@@ -30,6 +30,11 @@ import com.l2jserver.service.database.DatabaseService;
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public interface WorldIDService extends Service {
/**
* Load all {@link ObjectID} from the database
*/
void load();
/**
* Tries to resolve an ID based on its raw value
*
@@ -43,7 +48,23 @@ public interface WorldIDService extends Service {
*/
<I extends ObjectID<?>> I resolve(int id);
/**
* Adds a new ID to be managed by this service
*
* @param <I>
* the ID type
* @param id
* the id
*/
<I extends ObjectID<?>> void add(I id);
/**
* Decouples an ID from this service
*
* @param <I>
* the ID type
* @param id
* the id
*/
<I extends ObjectID<?>> void remove(I id);
}

View File

@@ -50,7 +50,7 @@ import com.l2jserver.util.factory.CollectionFactory;
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
@Depends({ LoggingService.class, TemplateService.class, ScriptingService.class,
DatabaseService.class })
DatabaseService.class, WorldIDService.class })
public class WorldServiceImpl extends AbstractService implements WorldService {
/**
* The logger
@@ -66,15 +66,22 @@ public class WorldServiceImpl extends AbstractService implements WorldService {
* The world event dispatcher
*/
private final WorldEventDispatcherImpl dispatcher;
/**
* The {@link WorldIDService}
*/
private final WorldIDService idService;
@Inject
public WorldServiceImpl(WorldEventDispatcher dispatcher) {
public WorldServiceImpl(WorldEventDispatcher dispatcher,
WorldIDService idService) {
this.dispatcher = (WorldEventDispatcherImpl) dispatcher;
this.idService = idService;
}
@Override
protected void doStart() throws ServiceStartException {
objects.clear();
idService.load();
}
@Override

View File

@@ -22,8 +22,9 @@ import org.htmlparser.tags.BodyTag;
import org.htmlparser.util.NodeList;
/**
* @author <a href="http://www.rogiel.com">Rogiel</a>
* Lineage 2 {@link Tag}: <tt>body</tt>
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class L2BodyTag extends BodyTag {
private static final long serialVersionUID = 1L;

View File

@@ -17,21 +17,17 @@
package com.l2jserver.util.html;
import org.htmlparser.Tag;
import org.htmlparser.nodes.TagNode;
import org.htmlparser.tags.Span;
/**
* @author <a href="http://www.rogiel.com">Rogiel</a>
* Lineage 2 {@link Tag}: <tt>br</tt>
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class L2BrTag extends Span {
private static final long serialVersionUID = 1L;
public L2BrTag() {
super.setTagName("br");
Tag end = new TagNode();
end.setTagName("/br");
super.setEndTag(end);
super.setEmptyXmlTag(true);
}
}

View File

@@ -21,8 +21,9 @@ import org.htmlparser.nodes.TagNode;
import org.htmlparser.tags.Span;
/**
* @author <a href="http://www.rogiel.com">Rogiel</a>
* Lineage 2 {@link Tag}: <tt>center</tt>
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class L2CenterTag extends Span {
private static final long serialVersionUID = 1L;

View File

@@ -22,8 +22,9 @@ import org.htmlparser.tags.Div;
import org.htmlparser.util.NodeList;
/**
* @author <a href="http://www.rogiel.com">Rogiel</a>
* Lineage 2 {@link Tag}: <tt>div</tt>
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class L2DivTag extends Div {
private static final long serialVersionUID = 1L;

View File

@@ -22,8 +22,9 @@ import org.htmlparser.tags.Span;
import org.htmlparser.util.NodeList;
/**
* @author <a href="http://www.rogiel.com">Rogiel</a>
* Lineage 2 {@link Tag}: <tt>font</tt>
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class L2FontTag extends Span {
private static final long serialVersionUID = 1L;

View File

@@ -22,6 +22,8 @@ import org.htmlparser.tags.HeadTag;
import org.htmlparser.util.NodeList;
/**
* Lineage 2 {@link Tag}: <tt>head</tt>
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class L2HeadTag extends HeadTag {

View File

@@ -22,8 +22,9 @@ import org.htmlparser.tags.Html;
import org.htmlparser.util.NodeList;
/**
* @author <a href="http://www.rogiel.com">Rogiel</a>
* Lineage 2 {@link Tag}: <tt>html</tt>
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class L2HtmlTag extends Html {
private static final long serialVersionUID = 1L;

View File

@@ -21,6 +21,8 @@ import org.htmlparser.nodes.TagNode;
import org.htmlparser.tags.ImageTag;
/**
* Lineage 2 {@link Tag}: <tt>img</tt>
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class L2ImageTag extends ImageTag {
@@ -31,6 +33,5 @@ public class L2ImageTag extends ImageTag {
Tag end = new TagNode();
end.setTagName("/img");
super.setEndTag(end);
super.setEmptyXmlTag(true);
}
}

View File

@@ -22,6 +22,8 @@ import org.htmlparser.tags.LinkTag;
import org.htmlparser.util.NodeList;
/**
* Lineage 2 {@link Tag}: <tt>a</tt>
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class L2LinkTag extends LinkTag {
@@ -33,6 +35,5 @@ public class L2LinkTag extends LinkTag {
end.setTagName("/a");
super.setEndTag(end);
super.setChildren(new NodeList());
super.setEmptyXmlTag(true);
}
}

View File

@@ -17,21 +17,17 @@
package com.l2jserver.util.html;
import org.htmlparser.Tag;
import org.htmlparser.nodes.TagNode;
import org.htmlparser.tags.Span;
/**
* @author <a href="http://www.rogiel.com">Rogiel</a>
* Lineage 2 {@link Tag}: <tt>p</tt>
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class L2NewLineTag extends Span {
private static final long serialVersionUID = 1L;
public L2NewLineTag() {
super.setTagName("p");
Tag end = new TagNode();
end.setTagName("/pp");
super.setEndTag(end);
super.setEmptyXmlTag(true);
}
}

View File

@@ -22,6 +22,8 @@ import org.htmlparser.tags.TitleTag;
import org.htmlparser.util.NodeList;
/**
* Lineage 2 {@link Tag}: <tt>title</tt>
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class L2TitleTag extends TitleTag {

View File

@@ -0,0 +1,151 @@
/*
* 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.util.html.markup;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Pattern;
import org.htmlparser.Tag;
import org.htmlparser.nodes.TextNode;
import org.htmlparser.tags.HeadTag;
import org.htmlparser.tags.Html;
import org.htmlparser.tags.TitleTag;
import com.l2jserver.util.factory.CollectionFactory;
import com.l2jserver.util.html.L2BodyTag;
import com.l2jserver.util.html.L2HeadTag;
import com.l2jserver.util.html.L2HtmlTag;
import com.l2jserver.util.html.L2TitleTag;
/**
* This an helper class used to build HTML documents. You should implement
* {@link HtmlTemplate} as an anonymous class:
*
* <pre>
* final HtmlTemplate template = new HtmlTemplate(&quot;Template implementation sample&quot;) {
* &#064;Override
* public void build(MarkupTag body) {
* body.text(&quot;Hello world!&quot;).br().text(&quot;New line!&quot;);
* }
* };
* final String html = template.toHtmlString();
* </pre>
*
* Using the {@link Html} object (from {@link #build()}) you can obtain the HTML
* code using {@link Html#toHtml()}.
* <p>
* The generated code will be the smaller possible because the client has packet
* size limitations, it will not contain any formatting.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public abstract class HtmlTemplate {
/**
* The template title (will be displayed in the game window)
*/
private final String title;
/**
* The template variables
*/
private Map<String, String> variables = CollectionFactory.newMap();
/**
* Creates a new instance
*
* @param title
* the title
*/
public HtmlTemplate(String title) {
this.title = title;
}
/**
* Creates a new instance without a title
*/
public HtmlTemplate() {
this(null);
}
/**
* Build the HTML structure
*
* @param body
* the body HTML node
*/
protected abstract void build(MarkupTag body);
/**
* Replace the variables in the template
*
* @param template
* the generated template HTML
* @return the HTML with variables replaced
*/
public String replace(String template) {
for (final Entry<String, String> variable : variables.entrySet()) {
template = template.replaceAll(
Pattern.quote("${" + variable.getKey() + "}"),
variable.getValue());
}
return template;
}
/**
* Register an variable for this template
*
* @param name
* the name
* @param value
* the value
*/
public void register(String name, String value) {
variables.put(name, value);
}
/**
* Creates a new {@link Html} object using the {@link HtmlTemplate} provided
* in the constructor. This method can be invoked multiple times.
*
* @return the {@link Html} object
*/
public Html build() {
final Html html = new L2HtmlTag();
if (title != null) {
final HeadTag head = new L2HeadTag();
final TitleTag title = new L2TitleTag();
html.getChildren().add(head);
head.getChildren().add(title);
title.getChildren().add(new TextNode(this.title));
}
final Tag body = new L2BodyTag();
html.getChildren().add(body);
this.build(new MarkupTag(body));
return html;
}
/**
* Generates the HTML code for this template. It also replaces the
* variables.
*
* @return the HTML code
*/
public String toHtmlString() {
return this.replace(build().toHtml());
}
}

View File

@@ -1,57 +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.util.html.markup;
import org.htmlparser.nodes.TextNode;
import org.htmlparser.tags.HeadTag;
import org.htmlparser.tags.Html;
import org.htmlparser.tags.TitleTag;
import com.l2jserver.util.html.L2HeadTag;
import com.l2jserver.util.html.L2HtmlTag;
import com.l2jserver.util.html.L2TitleTag;
/**
* @author <a href="http://www.rogiel.com">Rogiel</a>
*
*/
public class Markup {
private final Builder builder;
private final String title;
public Markup(String title, Builder builder) {
this.builder = builder;
this.title = title;
}
public Html build() {
final Html html = new L2HtmlTag();
final HeadTag head = new L2HeadTag();
final TitleTag title = new L2TitleTag();
head.getChildren().add(head);
head.getChildren().add(title);
title.getChildren().add(new TextNode(this.title));
this.builder.build(new MarkupTag(html));
return html;
}
public interface Builder {
void build(MarkupTag body);
}
}

View File

@@ -28,32 +28,78 @@ import com.l2jserver.util.html.L2LinkTag;
import com.l2jserver.util.html.L2NewLineTag;
/**
* @author <a href="http://www.rogiel.com">Rogiel</a>
* This is an helper class that helps creating new tags in the HTML document.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class MarkupTag {
/**
* The current tag
*/
private final Tag tag;
/**
* The parent {@link MarkupTag}
*/
private final MarkupTag parent;
/**
* Creates a new instance with a parent
*
* @param tag
* the tag
* @param parent
* the parent
*/
public MarkupTag(Tag tag, MarkupTag parent) {
this.tag = tag;
this.parent = parent;
}
/**
* Creates a new instance without a parent
*
* @param tag
* the tag
*/
public MarkupTag(Tag tag) {
this(tag, null);
}
/**
* Adds an attribute to the current tag
*
* @param name
* the attribute name
* @param value
* the attribute value
* @return this {@link MarkupTag}
*/
public MarkupTag attr(String name, String value) {
tag.setAttribute(name, value);
return this;
}
/**
* Adds a plain text to the tag. It will not use any formatting.
*
* @param text
* the text
* @return this {@link MarkupTag}
*/
public MarkupTag text(String text) {
tag.getChildren().add(new TextNode(text));
return this;
}
/**
* Adds a plain text to the tag, use the color formatting.
*
* @param text
* the text
* @param color
* the text color
* @return this {@link MarkupTag}
*/
public MarkupTag text(String text, String color) {
final Tag font = new L2FontTag();
font.setAttribute("color", color);
@@ -62,30 +108,61 @@ public class MarkupTag {
return this;
}
/**
* Creates a new DIV element
*
* @return this div {@link MarkupTag}
*/
public MarkupTag div() {
final Tag tag = new L2DivTag();
this.tag.getChildren().add(tag);
return new MarkupTag(tag, this);
}
/**
* Inserts a line break
*
* @return this {@link MarkupTag}
*/
public MarkupTag br() {
final Tag tag = new L2BrTag();
this.tag.getChildren().add(tag);
return this;
}
/**
* Inserts a new paragraph
*
* @return this {@link MarkupTag}
*/
public MarkupTag p() {
final Tag tag = new L2NewLineTag();
this.tag.getChildren().add(tag);
return this;
}
/**
* Creates a new CENTER element. Text inside this element will be centered.
*
* @return this CENTER {@link MarkupTag}
*/
public MarkupTag center() {
final Tag tag = new L2CenterTag();
this.tag.getChildren().add(tag);
return new MarkupTag(this.tag, this);
}
/**
* Adds an image
*
* @param src
* the image source
* @param height
* the height
* @param width
* the width
* @return this {@link MarkupTag}
*/
public MarkupTag addImage(String src, int height, int width) {
final Tag tag = new L2ImageTag();
this.tag.getChildren().add(tag);
@@ -95,6 +172,15 @@ public class MarkupTag {
return this;
}
/**
* Adds a link
*
* @param text
* the link text
* @param action
* the link action (will automatically append "bypass -h")
* @return
*/
public MarkupTag addLink(String text, String action) {
final Tag tag = new L2LinkTag();
this.tag.getChildren().add(tag);
@@ -103,6 +189,11 @@ public class MarkupTag {
return this;
}
/**
* Close this tag and return the parent element
*
* @return the parent element, if any.
*/
public MarkupTag close() {
return parent;
}

View File

@@ -39,9 +39,9 @@ import com.l2jserver.model.world.player.event.PlayerListener;
import com.l2jserver.model.world.player.event.PlayerSpawnEvent;
import com.l2jserver.service.ServiceManager;
import com.l2jserver.service.ServiceStartException;
import com.l2jserver.service.game.world.WorldIDService;
import com.l2jserver.service.game.world.WorldService;
import com.l2jserver.service.game.world.event.WorldEventDispatcher;
import com.l2jserver.service.game.world.id.WorldIDService;
public class WorldEventDispatcherImplTest {
private WorldService world;

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 script.template.actor.character;
import com.google.inject.Inject;
import com.l2jserver.model.id.template.CharacterTemplateID;
import com.l2jserver.model.id.template.factory.CharacterTemplateIDFactory;
import com.l2jserver.model.world.L2Character;
import com.l2jserver.model.world.character.CharacterClass;
import com.l2jserver.util.dimensional.Point;
public class ${javaClassName}Template extends ${parent}Template {
@Inject
public ${javaClassName}Template(CharacterTemplateIDFactory factory) {
super(factory.createID(${ClassId}.id), ${ClassId}, Point.fromXYZ(${x}, ${y}, ${z}));
// ATTRIBUTES
attributes.intelligence = ${_INT};
attributes.strength = ${STR};
attributes.concentration = ${CON};
attributes.mentality = ${MEN};
attributes.dexterity = ${DEX};
attributes.witness = ${WIT};
attributes.physicalAttack = ${P_ATK};
attributes.magicalAttack = ${M_ATK};
attributes.physicalDefense = ${P_DEF};
attributes.magicalDefense = ${M_DEF};
attributes.attackSpeed = ${P_SPD};
attributes.castSpeed = ${M_SPD};
attributes.accuracy = ${ACC};
attributes.criticalChance = ${CRITICAL};
attributes.evasionChance = ${EVASION};
attributes.moveSpeed = ${MOVE_SPD};
attributes.maxWeigth = ${_LOAD};
attributes.craft = ${canCraft};
}
protected ${javaClassName}Template(CharacterTemplateID id,
CharacterClass characterClass, Point spawnLocation) {
super(id, characterClass, spawnLocation);
}
@Override
public L2Character create() {
final L2Character character = super.create();
// TODO register skills
return character;
}
}

View File

@@ -0,0 +1,126 @@
/*
* 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.tool.conversor.npctemplate;
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.io.IOUtils;
import com.l2jserver.model.world.AbstractActor.Race;
import com.l2jserver.model.world.character.CharacterClass;
import com.l2jserver.util.factory.CollectionFactory;
public class NPCTemplateConverter {
private static final String JDBC_URL = "jdbc:mysql://localhost/l2j-old";
private static final String JDBC_USERNAME = "l2j";
private static final String JDBC_PASSWORD = "changeme";
private static String template;
private static Map<CharacterClass, String> parents = CollectionFactory
.newMap();
public static void main(String[] args) throws SQLException, IOException,
ClassNotFoundException {
Class.forName("com.mysql.jdbc.Driver");
template = IOUtils.toString(NPCTemplateConverter.class
.getResourceAsStream("CharacterTemplateBase.txt"));
System.out.println("Generating template classes...");
final Connection conn = DriverManager.getConnection(JDBC_URL,
JDBC_USERNAME, JDBC_PASSWORD);
try {
final PreparedStatement st = conn
.prepareStatement("SELECT * FROM char_templates");
try {
st.execute();
final ResultSet rs = st.getResultSet();
while (rs.next()) {
String[] result = generateJavaClass(rs);
IOUtils.write(result[0], new FileOutputStream(
"generated/template/character/" + result[1]));
}
} finally {
st.close();
}
} finally {
conn.close();
}
}
private static String[] generateJavaClass(ResultSet rs) throws SQLException {
String name = "";
String template = NPCTemplateConverter.template;
for (int i = 1; i < rs.getMetaData().getColumnCount() + 1; i++) {
template = replace(template, rs.getMetaData().getColumnName(i),
rs.getString(i));
if (rs.getMetaData().getColumnName(i).equals("ClassId")) {
final CharacterClass c = CharacterClass.fromID(Integer
.parseInt(rs.getString(i)));
name = camelCase(c.name()) + "Template.java";
}
}
return new String[] { template, name };
}
private static String replace(String template, String key, String value) {
if (key.equals("ClassId")) {
final CharacterClass c = CharacterClass.fromID(Integer
.parseInt(value));
value = "CharacterClass." + c.name();
String parent;
if (c.parent != null) {
parent = parents.get(c.parent);
} else {
parent = "Abstract" + camelCase(c.race.name()) + "Character";
}
parents.put(c, camelCase(c.name()));
template = template.replaceAll("\\$\\{parent\\}", parent);
template = template.replaceAll("\\$\\{javaClassName\\}",
camelCase(c.name()));
}
if (key.equals("RaceId"))
value = Race.fromOption(Integer.parseInt(value)).name();
if (key.equals("canCraft"))
value = (value.equals("1") ? "true" : "false");
return template.replaceAll("\\$\\{" + key + "\\}", value);
}
private static String camelCase(String c) {
Pattern p = Pattern.compile("[a-zA-Z0-9]+");
Matcher m = p.matcher(c.replaceAll("_", " "));
StringBuffer result = new StringBuffer();
String word;
while (m.find()) {
word = m.group();
result.append(word.substring(0, 1).toUpperCase()
+ word.substring(1).toLowerCase());
}
return result.toString();
}
}