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

Move model and ID abstract classes to l2jserver2-common

This commit is contained in:
2011-12-04 13:00:20 -02:00
parent cb96d0f5cc
commit 6b34407142
14 changed files with 102 additions and 724 deletions

View File

@@ -178,6 +178,12 @@
<artifactId>htmlparser</artifactId>
<version>2.1</version>
<type>jar</type>
<exclusions>
<exclusion>
<groupId>com.sun</groupId>
<artifactId>tools</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- utils -->
<dependency>

View File

@@ -21,7 +21,9 @@ import static org.jboss.netty.channel.Channels.pipeline;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.handler.logging.LoggingHandler;
import org.jboss.netty.handler.timeout.IdleStateHandler;
import org.jboss.netty.logging.InternalLogLevel;
import org.jboss.netty.util.HashedWheelTimer;
import com.google.inject.Guice;
import com.google.inject.Inject;
@@ -33,6 +35,7 @@ import com.l2jserver.game.net.codec.Lineage2FrameEncoder;
import com.l2jserver.game.net.codec.Lineage2PacketReader;
import com.l2jserver.game.net.codec.Lineage2PacketWriter;
import com.l2jserver.game.net.handler.Lineage2PacketHandler;
import com.l2jserver.game.net.handler.Lineage2TimeoutHandler;
import com.l2jserver.service.game.world.WorldService;
import com.l2jserver.service.network.NettyNetworkService;
import com.l2jserver.service.network.NetworkService;
@@ -78,6 +81,9 @@ public class Lineage2PipelineFactory implements ChannelPipelineFactory {
@Override
public ChannelPipeline getPipeline() throws Exception {
final ChannelPipeline pipeline = pipeline();
pipeline.addLast("timeout.tiner", new IdleStateHandler(
new HashedWheelTimer(), 30, 30, 0));
pipeline.addLast("frame.encoder", new Lineage2FrameEncoder());
pipeline.addLast("frame.decoder", new Lineage2FrameDecoder());
@@ -95,8 +101,10 @@ public class Lineage2PipelineFactory implements ChannelPipelineFactory {
pipeline.addLast("logger", new LoggingHandler(InternalLogLevel.DEBUG,
true));
final Lineage2TimeoutHandler timeoutHandler = new Lineage2TimeoutHandler();
pipeline.addLast("packet.handler", new Lineage2PacketHandler(
nettyNetworkService, worldService));
nettyNetworkService, worldService, timeoutHandler));
pipeline.addLast("timeout.handler", timeoutHandler);
return pipeline;
}

View File

@@ -48,6 +48,10 @@ public class Lineage2PacketHandler extends SimpleChannelHandler {
* The {@link WorldService} instance
*/
private final WorldService worldService;
/**
* The timeout handler is responsible for disconnecting idle clients.
*/
private final Lineage2TimeoutHandler timeoutHandler;
/**
* The Lineage 2 connection
*/
@@ -60,11 +64,14 @@ public class Lineage2PacketHandler extends SimpleChannelHandler {
* the netty network service
* @param worldService
* the world service
* @param timeoutHandler
* the timeout handler
*/
public Lineage2PacketHandler(NettyNetworkService nettyNetworkService,
WorldService worldService) {
WorldService worldService, Lineage2TimeoutHandler timeoutHandler) {
this.nettyNetworkService = nettyNetworkService;
this.worldService = worldService;
this.timeoutHandler = timeoutHandler;
}
@Override
@@ -73,6 +80,7 @@ public class Lineage2PacketHandler extends SimpleChannelHandler {
connection = new Lineage2Client(worldService, nettyNetworkService,
e.getChannel());
connection.getPacketWriter().setConnection(connection);
timeoutHandler.setConnection(connection);
nettyNetworkService.register(connection);

View File

@@ -0,0 +1,58 @@
/*
* 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.handler;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.handler.timeout.IdleStateAwareChannelHandler;
import org.jboss.netty.handler.timeout.IdleStateEvent;
import com.l2jserver.game.net.Lineage2Client;
/**
* @author <a href="http://www.rogiel.com">Rogiel</a>
*
*/
public class Lineage2TimeoutHandler extends IdleStateAwareChannelHandler {
/**
* The Lineage 2 connection
*/
private Lineage2Client connection;
@Override
public void channelIdle(ChannelHandlerContext ctx, IdleStateEvent e)
throws Exception {
if (connection != null) {
connection.close();
}
super.channelIdle(ctx, e);
}
/**
* @return the connection
*/
protected Lineage2Client getConnection() {
return connection;
}
/**
* @param connection
* the connection to set
*/
protected void setConnection(Lineage2Client connection) {
this.connection = connection;
}
}

View File

@@ -1,110 +0,0 @@
/*
* 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.model;
import com.google.common.base.Preconditions;
import com.l2jserver.model.id.ID;
/**
* Simple model interface implementing {@link ID} related methods
*
* @param <T>
* the ID type used to represent this {@link Model}
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public abstract class AbstractModel<T extends ID<?>> implements Model<T> {
/**
* The object id
*/
protected T id;
/**
* The database object state
*/
protected transient ObjectDesire desire = ObjectDesire.INSERT;
@Override
public T getID() {
return id;
}
@Override
public void setID(T ID) {
Preconditions.checkState(id == null, "ID is already set");
desireInsert();
this.id = ID;
}
@Override
public ObjectDesire getObjectDesire() {
return desire;
}
@Override
public void setObjectDesire(ObjectDesire desire) {
if (desire == null)
desire = ObjectDesire.NONE;
this.desire = desire;
}
/**
* Set this object desire to {@link ObjectDesire#UPDATE}. If the desire is
* {@link ObjectDesire#INSERT} or {@link ObjectDesire#DELETE} the desire
* will not be changed.
*/
@SuppressWarnings("javadoc")
protected void desireUpdate() {
if (this.desire != ObjectDesire.INSERT
&& this.desire != ObjectDesire.DELETE)
this.desire = ObjectDesire.UPDATE;
}
/**
* Set this object desire to {@link ObjectDesire#INSERT}. If the desire is
* {@link ObjectDesire#DELETE} the desire will not be changed.
*/
@SuppressWarnings("javadoc")
protected void desireInsert() {
if (this.desire != ObjectDesire.DELETE)
this.desire = ObjectDesire.INSERT;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
AbstractModel<?> other = (AbstractModel<?>) obj;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
return true;
}
}

View File

@@ -1,104 +0,0 @@
/*
* 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.model;
import com.l2jserver.model.id.ID;
import com.l2jserver.service.database.DatabaseService;
/**
* Base model. Each object model must implement this interface to be able to be
* inserted into the database.
*
* @param <T>
* the {@link ID} type used to represent this {@link Model}
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public interface Model<T extends ID<?>> {
/**
* @return the object ID
*/
T getID();
/**
* Please note that the ID can only be set one time. Once it has been set,
* it cannot be changed and a {@link IllegalStateException} will be thrown
* if trying to change the ID.
*
* @param ID
* the object ID to set
* @throws IllegalStateException
* if the ID was already set
*/
void setID(T ID) throws IllegalStateException;
/**
* Each object has an desire. Desires express what the
* {@link DatabaseService} should do with the object. The service
* automatically keep tracks of every database object (and release them when
* they are garbage collected).
*
* @return the database object desire
*/
ObjectDesire getObjectDesire();
/**
* Each object has an desire. Desires express what the
* {@link DatabaseService} should do with the object. The service
* automatically keep tracks of every database object (and release them when
* they are garbage collected).
*
* @param desire
* the database object desire to set
*/
void setObjectDesire(ObjectDesire desire);
/**
* Indicated what the object wants to do in the database. It indicates
* whether the object should be inserted, updated or deleted from the
* database.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public enum ObjectDesire {
/**
* Don't do anything
*/
NONE,
/**
* Insert a new object into database.
* <p>
* If the primary key is auto generated by the database a clone of this
* object will be created.<br>
* If the primary key is <b>not</b> auto generated by the database, an
* database exception will occur.
*/
INSERT,
/**
* Updates the object in the database.
* <p>
* If the object is not in the database nothing will happen.
*/
UPDATE,
/**
* Deletes the object from the database.
* <p>
* If tge object is not in the database nothing will happen.
*/
DELETE;
}
}

View File

@@ -1,48 +0,0 @@
/*
* 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.model.id;
import com.l2jserver.model.Model;
/**
* This is an abstract ID for most model objects that do not extend
* {@link ObjectID}.
*
* @param <T>
* the raw id type
* @param <O>
* the model this {@link ID} provides
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public abstract class AbstractModelID<T, O extends Model<? extends ID<T>>>
extends ID<T> {
/**
* @param id
* the id
*/
protected AbstractModelID(T id) {
super(id);
}
/**
* @return the {@link Model} object associated with this
* {@link AbstractModelID}. <tt>null</tt> if {@link Model} does not
* exists.
*/
public abstract O getObject();
}

View File

@@ -1,81 +0,0 @@
/*
* 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.model.id;
import com.google.inject.Inject;
/**
* The ID interface. Each object must be represented by an unique ID.
*
* @param <T>
* the raw id type
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public abstract class ID<T> {
/**
* The id itself
*/
protected final T id;
/**
* @param id
* the raw id
*/
@Inject
protected ID(T id) {
this.id = id;
}
/**
* @return the id
*/
public T getID() {
return id;
}
@Override
public String toString() {
return this.getClass().getSimpleName() + " [id=" + id + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + id.hashCode() + this.getClass().hashCode();
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
@SuppressWarnings("rawtypes")
ID other = (ID) obj;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
return true;
}
}

View File

@@ -1,73 +0,0 @@
/*
* 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.model.id.compound;
import com.l2jserver.model.id.ID;
/**
* The compound {@link ID} is composed of two IDs.
*
* @param <T1>
* the first {@link ID} type
* @param <T2>
* the second {@link ID} type
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class AbstractCompoundID<T1, T2> extends ID<AbstractCompoundID<T1, T2>> {
/**
* The first ID
*/
private final T1 id1;
/**
* The second ID
*/
private final T2 id2;
/**
* Creates a new compound ID
*
* @param id1
* the first id
* @param id2
* the second id
*/
protected AbstractCompoundID(T1 id1, T2 id2) {
super(null);
this.id1 = id1;
this.id2 = id2;
}
/**
* @return the first id
*/
public T1 getID1() {
return id1;
}
/**
* @return the second id
*/
public T2 getID2() {
return id2;
}
@Override
public AbstractCompoundID<T1, T2> getID() {
return this;
}
}

View File

@@ -1,163 +0,0 @@
/*
* 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.model.id.object.allocator;
import java.util.BitSet;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.l2jserver.util.PrimeFinder;
/**
* The {@link BitSet} id allocator allocates new IDs backed by an {@link BitSet}
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class BitSetIDAllocator implements IDAllocator {
/**
* The logger
*/
private static final Logger log = LoggerFactory
.getLogger(BitSetIDAllocator.class);
/**
* Lock to guarantee synchronization
*/
private Lock lock = new ReentrantLock();
/**
* Available IDs
*/
private BitSet ids = new BitSet();
/**
* Amount of free ids
*/
private AtomicInteger freeIdCount = new AtomicInteger();
/**
* Next free ID
*/
private AtomicInteger nextId = new AtomicInteger();
/**
* Initializes this allocator
*/
public void init() {
ids = new BitSet(PrimeFinder.nextPrime(100000));
ids.clear();
freeIdCount = new AtomicInteger(ALLOCABLE_IDS);
nextId = new AtomicInteger(ids.nextClearBit(0));
log.info("BitSet IDAllocator initialized. Next available ID is {}",
nextId.get());
}
@Override
public void allocate(int id) {
if (ids.get(id - FIRST_ID))
throw new IDAllocatorException("ID not allocated");
log.debug("Allocating ID {}", id);
lock.lock();
try {
if (id < FIRST_ID)
return;
ids.set(id - FIRST_ID);
nextId = new AtomicInteger(ids.nextClearBit(0));
} finally {
lock.unlock();
}
}
@Override
public int allocate() {
lock.lock();
try {
final int newID = nextId.get();
ids.set(newID);
freeIdCount.decrementAndGet();
if (log.isDebugEnabled())
log.debug("Allocated a new ID {}", newID + FIRST_ID);
int nextFree = ids.nextClearBit(newID);
if (nextFree < 0) {
nextFree = ids.nextClearBit(0);
}
if (nextFree < 0) {
if (ids.size() < ALLOCABLE_IDS) {
increaseBitSetCapacity();
} else {
log.error("ID exhaustion");
throw new IDAllocatorException("ID exhaustion");
}
}
nextId.set(nextFree);
return newID + FIRST_ID;
} finally {
lock.unlock();
}
}
@Override
public void release(int id) {
if (id < FIRST_ID)
throw new IDAllocatorException(
"Can't release ID, smaller then initial ID");
if (!ids.get(id - FIRST_ID))
throw new IDAllocatorException("ID not allocated");
log.debug("Releasing allocated ID {}", id);
lock.lock();
try {
ids.clear(id - FIRST_ID);
freeIdCount.incrementAndGet();
} finally {
lock.unlock();
}
}
@Override
public void clear() {
ids.clear();
}
/**
* Increases the {@link BitSet} capacity
*/
private void increaseBitSetCapacity() {
log.debug("Increasing BitSet capacity from {}", ids.size());
BitSet newBitSet = new BitSet(
PrimeFinder.nextPrime((getAllocatedIDs() * 11) / 10));
newBitSet.or(ids);
ids = newBitSet;
}
@Override
public int getAllocatedIDs() {
return ALLOCABLE_IDS - getFreeIDs();
}
@Override
public int getFreeIDs() {
return freeIdCount.get();
}
}

View File

@@ -1,80 +0,0 @@
/*
* 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.model.id.object.allocator;
/**
* The ID allocator is used to alloc new ID and to release IDs that aren't used
* anymore.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public interface IDAllocator {
/**
* The first ID ever allocated
*/
public final static int FIRST_ID = 0x10000000;
/**
* The last ID ever allocated
*/
public final static int LAST_ID = 0x7FFFFFFF;
/**
* Total of available IDs for allocation
*/
public final static int ALLOCABLE_IDS = LAST_ID - FIRST_ID;
/**
* This is method is used to register IDs as used at startup time.
*
* @param id
* the id
*/
void allocate(int id);
/**
* Allocates a new ID
*
* @return the allocated ID value
*/
int allocate();
/**
* Release an ID
*
* @param id
* the id
*/
void release(int id);
/**
* Release all allocated IDs
*/
void clear();
/**
* Get the amount of already allocated IDs
*
* @return allocated ids count
*/
int getAllocatedIDs();
/**
* Get the amount of IDs remaining to be allocated
*
* @return free ids count
*/
int getFreeIDs();
}

View File

@@ -1,62 +0,0 @@
/*
* 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.model.id.object.allocator;
/**
* Exception thrown by an {@link IDAllocator}.
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class IDAllocatorException extends RuntimeException {
/**
* The Java Serialization Serial
*/
private static final long serialVersionUID = 111195059766878062L;
/**
* Creates an empty instance of this exception
*/
public IDAllocatorException() {
super();
}
/**
* @param message
* the message
* @param cause
* the root cause
*/
public IDAllocatorException(String message, Throwable cause) {
super(message, cause);
}
/**
* @param message
* the message
*/
public IDAllocatorException(String message) {
super(message);
}
/**
* @param cause
* the root cause
*/
public IDAllocatorException(Throwable cause) {
super(cause);
}
}

View File

@@ -48,10 +48,29 @@ public class ActorEffectContainer implements Iterable<Effect> {
this.actor = actor;
}
/**
* Adds a new effect to the actor's effect container.
* <p>
* Please note that if the <i>same</i> effect object is already in this
* container, nothing no exception will be thrown and the effect will not be
* applied twice.
*
* @param effect
* the effect to be added
*/
public void addEffect(Effect effect) {
effects.add(effect);
}
/**
* Removes an effect that is attached to the actor's effect container.
* <p>
* Please note that if the effect is not in the container, no exception will
* be thrown.
*
* @param effect
* the effect to be removed
*/
public void removeEffect(Effect effect) {
effects.remove(effect);
}

View File

@@ -20,7 +20,7 @@
<site>
<id>l2jserver2</id>
<name>l2jserver2</name>
<url>scp:l2jserver@l2jserver.com/l2jserver2.com</url>
<url>scp:l2jserver2@l2jserver2.com/l2jserver2.com</url>
</site>
</distributionManagement>