1
0
mirror of https://github.com/Rogiel/l2jserver2 synced 2025-12-06 07:32:46 +00:00
Files
l2jserver2/l2jserver2-gameserver/src/main/java/com/l2jserver/game/net/Lineage2Client.java
Rogiel d9a2badd2d Implement the SimpleEffectService
The EffectService allows effect applying to Actors and its children
objects.
2011-10-16 15:27:18 -02:00

400 lines
11 KiB
Java

/*
* This file is part of l2jserver2 <l2jserver2.com>.
*
* l2jserver2 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.
*
* l2jserver2 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 l2jserver2. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.game.net;
import java.util.Set;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFuture;
import com.l2jserver.game.net.codec.Lineage2Decrypter;
import com.l2jserver.game.net.codec.Lineage2Encrypter;
import com.l2jserver.game.net.codec.Lineage2PacketReader;
import com.l2jserver.game.net.codec.Lineage2PacketWriter;
import com.l2jserver.game.net.packet.ServerPacket;
import com.l2jserver.game.net.packet.server.SM_ACTION_FAILED;
import com.l2jserver.game.net.packet.server.SM_COMMUNITY_HTML;
import com.l2jserver.game.net.packet.server.SM_HTML;
import com.l2jserver.game.net.packet.server.SM_SYSTEM_MESSAGE;
import com.l2jserver.model.id.object.CharacterID;
import com.l2jserver.model.template.item.ItemTemplate;
import com.l2jserver.model.world.Item;
import com.l2jserver.model.world.L2Character;
import com.l2jserver.service.game.world.WorldService;
import com.l2jserver.service.game.world.filter.impl.CharacterBroadcastFilter;
import com.l2jserver.service.network.NetworkService;
import com.l2jserver.util.factory.CollectionFactory;
import com.l2jserver.util.html.markup.HtmlTemplate;
/**
* This object connects the model (structure objects normally stored in the
* database) to the controller (protocol stuff).
* <p>
* This class also provides handy methods for {@link #write(ServerPacket)
* writing} and {@link #broadcast(ServerPacket) broadcasting} packets.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class Lineage2Client {
/**
* The connection channel
*/
private final Channel channel;
/**
* The character object
*/
private CharacterID characterID;
/**
* The Lineage 2 session
*/
private Lineage2Session session;
/**
* The client supported protocol version
*/
private ProtocolVersion version;
// services
/**
* The {@link NetworkService} instance. This service is used to retrieve the
* {@link Lineage2Client} based on an {@link CharacterID}.
*/
private final NetworkService networkService;
/**
* The {@link WorldService} instance. This service is used to dynamically
* generate knownlists.
*/
private final WorldService worldService;
/**
* Creates a new instance
*
* @param worldService
* the world service
* @param networkService
* the network service
* @param channel
* the channel
*/
public Lineage2Client(WorldService worldService,
NetworkService networkService, Channel channel) {
this.worldService = worldService;
this.networkService = networkService;
this.channel = channel;
}
/**
* @return the character
*/
public boolean hasCharacter() {
return characterID != null;
}
/**
* @return the character ID
*/
public CharacterID getCharacterID() {
return characterID;
}
/**
* @return the character
*/
public L2Character getCharacter() {
return characterID.getObject();
}
/**
* @param characterID
* the character ID to set
*/
public void setCharacterID(CharacterID characterID) {
this.characterID = characterID;
}
/**
* @return the session
*/
public Lineage2Session getSession() {
return session;
}
/**
* @param session
* the session to set
*/
public void setSession(Lineage2Session session) {
if (this.session != null)
throw new IllegalStateException("Session is already set!");
this.session = session;
}
/**
* @return the version
*/
public ProtocolVersion getVersion() {
return version;
}
/**
* @param version
* the version to set
*/
public void setVersion(ProtocolVersion version) {
this.version = version;
}
/**
* Check if the client supports an given version of the protocol. Note that
* if the protocol is not known false will always be returned.
*
* @param version
* the protocol version to test for support
* @return true if version is supported by the client
* @see com.l2jserver.game.net.ProtocolVersion#supports(com.l2jserver.game.net.ProtocolVersion)
*/
public boolean supports(ProtocolVersion version) {
if (version == null)
return false;
return version.supports(version);
}
/**
* Get the channel
*
* @return the channel
*/
public Channel getChannel() {
return channel;
}
/**
* Test if the client is still open.
* <p>
* Please note that the channel can be open but disconnected!
*
* @return true if the client is still open
* @see Channel#isOpen()
*/
public boolean isOpen() {
return channel.isOpen();
}
/**
* Test if the client is still connected
* <p>
* Please note that the channel can be open but disconnected!
*
* @return true if the client is still connected
* @see Channel#isConnected()
*/
public boolean isConnected() {
return channel.isConnected();
}
/**
* Writes an packet to this client
* <p>
* Please note that this method will <b>not</b> block for the packets to be
* sent. It is possible to check if the packet was sent successfully using
* the {@link ChannelFuture}.
*
* @param packet
* the packet
* @return the {@link ChannelFuture} that will be notified once the packet
* has been written.
*/
public ChannelFuture write(ServerPacket packet) {
return channel.write(packet);
}
/**
* Sends a string message to this client
*
* @param message
* the message
* @return the {@link ChannelFuture} that will be notified once the packet
* has been written.
*/
public ChannelFuture sendMessage(String message) {
return write(new SM_SYSTEM_MESSAGE(SystemMessage.S1).addString(message));
}
/**
* Sends a {@link SystemMessage} to this client
*
* @param message
* the {@link SystemMessage}
* @return the {@link ChannelFuture} that will be notified once the packet
* has been written.
*/
public ChannelFuture sendSystemMessage(SystemMessage message) {
return write(message.packet);
}
/**
* Sends a {@link SystemMessage} to this client
*
* @param message
* the {@link SystemMessage}
* @param args
* the arguments of the message, they will be automatically
* detected and inserted. See {@link SM_SYSTEM_MESSAGE} for more
* about supported formats.
* @return the {@link ChannelFuture} that will be notified once the packet
* has been written.
* @see SM_SYSTEM_MESSAGE
*/
public ChannelFuture sendSystemMessage(SystemMessage message,
Object... args) {
final SM_SYSTEM_MESSAGE packet = new SM_SYSTEM_MESSAGE(message);
for (final Object obj : args) {
if (obj instanceof String)
packet.addString((String) obj);
else if (obj instanceof ItemTemplate)
packet.addItem((ItemTemplate) obj);
else if (obj instanceof Item)
packet.addItem((Item) obj);
else if (obj instanceof Number)
packet.addNumber((Integer) obj);
}
return write(packet);
}
/**
* Sends a {@link SM_ACTION_FAILED} to the client.
* <p>
* This is an convenience method for <blockquote><code>
* conn.write(ActionFailedPacket.SHARED_INSTANCE);</code></blockquote>
*
* @return the {@link ChannelFuture} that will be notified once the packet
* has been written.
*/
public ChannelFuture sendActionFailed() {
return write(SM_ACTION_FAILED.SHARED_INSTANCE);
}
/**
* Sends a {@link SM_HTML} packet to the client. In the packet, the NPC will
* be null. If you wish to send the HTML with an NPC, you should send the
* packet directly.
* <p>
* This is an convenience method for <blockquote><code>
* conn.write(new SM_HTML(null, template));</code></blockquote>
*
* @param template
* the HTML template to be sent
* @return the {@link ChannelFuture} that will be notified once the packet
* has been written.
*/
public ChannelFuture sendHTML(HtmlTemplate template) {
return write(new SM_HTML(null, template));
}
/**
* Sends a {@link SM_COMMUNITY_HTML} packet to the client. HTML code is not
* displayed in the regular chat window, they will appear in a large one.
* <p>
* This is an convenience method for <blockquote><code>
* conn.write(new SM_COMMUNITY_HTML(template));</code></blockquote>
*
* @param template
* the HTML template to be sent
* @return the {@link ChannelFuture} that will be notified once the packet
* has been written.
*/
public ChannelFuture sendCommunityHTML(HtmlTemplate template) {
return write(new SM_COMMUNITY_HTML(template));
}
/**
* Broadcast a packet to all characters in this character knownlist.
* <p>
* Note that in the broadcasting process, this client will be included.
* <p>
* Please note that this method will <b>not</b> block for all packets to be
* sent. It is possible to check if all packets were sent successfully using
* the {@link ChannelFuture} instances.
*
* @param packet
* the packet
* @return an {@link Set} containing all {@link ChannelFuture} instances.
*/
public Set<ChannelFuture> broadcast(ServerPacket packet) {
final Set<ChannelFuture> futures = CollectionFactory.newSet();
for (final L2Character character : worldService
.iterable(new CharacterBroadcastFilter(characterID.getObject()))) {
final Lineage2Client conn = networkService.discover(character
.getID());
if (conn == null)
continue;
futures.add(conn.write(packet));
}
return futures;
}
/**
* Disconnects this client, without closing the channel.
*
* @return the {@link ChannelFuture}
*/
public ChannelFuture disconnect() {
return channel.disconnect();
}
/**
* Closes the channel of this client.
*
* @return the {@link ChannelFuture}
*/
public ChannelFuture close() {
return channel.close();
}
/**
* @return the client {@link Lineage2Decrypter}
*/
public Lineage2Decrypter getDecrypter() {
return (Lineage2Decrypter) channel.getPipeline().get(
Lineage2Decrypter.HANDLER_NAME);
}
/**
* @return the client {@link Lineage2Encrypter}
*/
public Lineage2Encrypter getEncrypter() {
return (Lineage2Encrypter) channel.getPipeline().get(
Lineage2Encrypter.HANDLER_NAME);
}
/**
* @return the client {@link Lineage2PacketReader}
*/
public Lineage2PacketReader getPacketReader() {
return (Lineage2PacketReader) channel.getPipeline().get(
Lineage2PacketReader.HANDLER_NAME);
}
/**
* @return the client {@link Lineage2PacketWriter}
*/
public Lineage2PacketWriter getPacketWriter() {
return (Lineage2PacketWriter) channel.getPipeline().get(
Lineage2PacketWriter.HANDLER_NAME);
}
}