From 54ef3c7fa2292963ef4326289b4011a4cd049846 Mon Sep 17 00:00:00 2001 From: rogiel Date: Thu, 28 Apr 2011 22:53:11 -0300 Subject: [PATCH] Change-Id: Ifa069a09d1b603781a2c9255d89b77cd6f25a359 --- .fbprefs | 127 +++++++++++++++++ .project | 6 + .../java/com/l2jserver/L2JServerRuntime.java | 9 ++ .../game/net/Lineage2Connection.java | 50 +++++++ .../game/net/Lineage2PipelineFactory.java | 36 +++++ .../game/net/codec/Lineage2Decoder.java | 33 +++-- .../game/net/codec/Lineage2Decrypter.java | 60 ++++++++ .../game/net/codec/Lineage2Encoder.java | 6 +- .../game/net/codec/Lineage2Encrypter.java | 58 ++++++++ .../game/net/codec/Lineage2PacketReader.java | 38 +++++ .../game/net/codec/Lineage2PacketWriter.java | 22 +++ .../net/handler/Lineage2PacketHandler.java | 26 ++++ .../game/net/packet/ClientPacket.java | 16 +++ .../packet/client/ProtocolVersionPacket.java | 30 ++++ .../game/net/packet/client/TestPacket.java | 15 -- .../java/com/l2jserver/model/world/Item.java | 31 ++++- .../com/l2jserver/model/world/Player.java | 36 ++--- .../java/com/l2jserver/model/world/World.java | 52 +++++++ .../model/world/capability/Listenable.java | 24 +++- .../model/world/event/WorldEvent.java | 9 +- .../world/event/WorldEventDispatcher.java | 16 +++ .../model/world/event/WorldListener.java | 17 ++- .../model/world/filter/AndFilter.java | 8 +- .../model/world/filter/NotFilter.java | 6 +- .../model/world/filter/OrFilter.java | 8 +- .../model/world/filter/WorldFilters.java | 12 +- ...orldFilter.java => WorldObjectFilter.java} | 2 +- .../model/world/filter/impl/IDFilter.java | 4 +- .../world/filter/impl/InstanceFilter.java | 19 +++ .../model/world/filter/impl/RangeFilter.java | 4 +- .../model/world/item/ItemDropEvent.java | 38 +++++ .../model/world/iterator/FilterIterator.java | 55 ++++++++ .../model/world/player/PlayerSpawnEvent.java | 6 + .../model/world/player/TestEvent.java | 6 + .../game/world/WorldEventDispatcher.java | 8 -- .../service/game/world/WorldServiceImpl.java | 18 ++- .../service/network/NettyNetworkService.java | 20 ++- .../com/l2jserver/model/world/WorldTest.java | 130 ++++++++++++++++++ 38 files changed, 962 insertions(+), 99 deletions(-) create mode 100644 .fbprefs create mode 100644 src/main/java/com/l2jserver/L2JServerRuntime.java create mode 100644 src/main/java/com/l2jserver/game/net/Lineage2Connection.java create mode 100644 src/main/java/com/l2jserver/game/net/Lineage2PipelineFactory.java create mode 100644 src/main/java/com/l2jserver/game/net/codec/Lineage2Decrypter.java create mode 100644 src/main/java/com/l2jserver/game/net/codec/Lineage2Encrypter.java create mode 100644 src/main/java/com/l2jserver/game/net/codec/Lineage2PacketReader.java create mode 100644 src/main/java/com/l2jserver/game/net/codec/Lineage2PacketWriter.java create mode 100644 src/main/java/com/l2jserver/game/net/handler/Lineage2PacketHandler.java create mode 100644 src/main/java/com/l2jserver/game/net/packet/client/ProtocolVersionPacket.java delete mode 100644 src/main/java/com/l2jserver/game/net/packet/client/TestPacket.java create mode 100644 src/main/java/com/l2jserver/model/world/World.java create mode 100644 src/main/java/com/l2jserver/model/world/event/WorldEventDispatcher.java rename src/main/java/com/l2jserver/model/world/filter/{WorldFilter.java => WorldObjectFilter.java} (86%) create mode 100644 src/main/java/com/l2jserver/model/world/filter/impl/InstanceFilter.java create mode 100644 src/main/java/com/l2jserver/model/world/item/ItemDropEvent.java create mode 100644 src/main/java/com/l2jserver/model/world/iterator/FilterIterator.java create mode 100644 src/main/java/com/l2jserver/model/world/player/TestEvent.java delete mode 100644 src/main/java/com/l2jserver/service/game/world/WorldEventDispatcher.java create mode 100644 src/test/java/com/l2jserver/model/world/WorldTest.java diff --git a/.fbprefs b/.fbprefs new file mode 100644 index 000000000..3c5342714 --- /dev/null +++ b/.fbprefs @@ -0,0 +1,127 @@ +#FindBugs User Preferences +#Thu Apr 28 21:39:39 BRT 2011 +detectorAppendingToAnObjectOutputStream=AppendingToAnObjectOutputStream|true +detectorBadAppletConstructor=BadAppletConstructor|false +detectorBadResultSetAccess=BadResultSetAccess|true +detectorBadSyntaxForRegularExpression=BadSyntaxForRegularExpression|true +detectorBadUseOfReturnValue=BadUseOfReturnValue|true +detectorBadlyOverriddenAdapter=BadlyOverriddenAdapter|true +detectorBooleanReturnNull=BooleanReturnNull|true +detectorCallToUnsupportedMethod=CallToUnsupportedMethod|false +detectorCheckImmutableAnnotation=CheckImmutableAnnotation|true +detectorCheckTypeQualifiers=CheckTypeQualifiers|true +detectorCloneIdiom=CloneIdiom|true +detectorComparatorIdiom=ComparatorIdiom|true +detectorConfusedInheritance=ConfusedInheritance|true +detectorConfusionBetweenInheritedAndOuterMethod=ConfusionBetweenInheritedAndOuterMethod|true +detectorCrossSiteScripting=CrossSiteScripting|true +detectorDoInsideDoPrivileged=DoInsideDoPrivileged|true +detectorDontCatchIllegalMonitorStateException=DontCatchIllegalMonitorStateException|true +detectorDontIgnoreResultOfPutIfAbsent=DontIgnoreResultOfPutIfAbsent|true +detectorDontUseEnum=DontUseEnum|true +detectorDroppedException=DroppedException|true +detectorDumbMethodInvocations=DumbMethodInvocations|true +detectorDumbMethods=DumbMethods|true +detectorDuplicateBranches=DuplicateBranches|true +detectorEmptyZipFileEntry=EmptyZipFileEntry|true +detectorEqualsOperandShouldHaveClassCompatibleWithThis=EqualsOperandShouldHaveClassCompatibleWithThis|true +detectorFinalizerNullsFields=FinalizerNullsFields|true +detectorFindBadCast2=FindBadCast2|true +detectorFindBadForLoop=FindBadForLoop|true +detectorFindCircularDependencies=FindCircularDependencies|false +detectorFindDeadLocalStores=FindDeadLocalStores|true +detectorFindDoubleCheck=FindDoubleCheck|true +detectorFindEmptySynchronizedBlock=FindEmptySynchronizedBlock|true +detectorFindFieldSelfAssignment=FindFieldSelfAssignment|true +detectorFindFinalizeInvocations=FindFinalizeInvocations|true +detectorFindFloatEquality=FindFloatEquality|true +detectorFindHEmismatch=FindHEmismatch|true +detectorFindInconsistentSync2=FindInconsistentSync2|true +detectorFindJSR166LockMonitorenter=FindJSR166LockMonitorenter|true +detectorFindLocalSelfAssignment2=FindLocalSelfAssignment2|true +detectorFindMaskedFields=FindMaskedFields|true +detectorFindMismatchedWaitOrNotify=FindMismatchedWaitOrNotify|true +detectorFindNakedNotify=FindNakedNotify|true +detectorFindNonSerializableStoreIntoSession=FindNonSerializableStoreIntoSession|true +detectorFindNonSerializableValuePassedToWriteObject=FindNonSerializableValuePassedToWriteObject|true +detectorFindNonShortCircuit=FindNonShortCircuit|true +detectorFindNullDeref=FindNullDeref|true +detectorFindNullDerefsInvolvingNonShortCircuitEvaluation=FindNullDerefsInvolvingNonShortCircuitEvaluation|true +detectorFindOpenStream=FindOpenStream|true +detectorFindPuzzlers=FindPuzzlers|true +detectorFindRefComparison=FindRefComparison|true +detectorFindReturnRef=FindReturnRef|true +detectorFindRunInvocations=FindRunInvocations|true +detectorFindSelfComparison=FindSelfComparison|true +detectorFindSelfComparison2=FindSelfComparison2|true +detectorFindSleepWithLockHeld=FindSleepWithLockHeld|true +detectorFindSpinLoop=FindSpinLoop|true +detectorFindSqlInjection=FindSqlInjection|true +detectorFindTwoLockWait=FindTwoLockWait|true +detectorFindUncalledPrivateMethods=FindUncalledPrivateMethods|true +detectorFindUnconditionalWait=FindUnconditionalWait|true +detectorFindUninitializedGet=FindUninitializedGet|true +detectorFindUnrelatedTypesInGenericContainer=FindUnrelatedTypesInGenericContainer|true +detectorFindUnreleasedLock=FindUnreleasedLock|true +detectorFindUnsatisfiedObligation=FindUnsatisfiedObligation|true +detectorFindUnsyncGet=FindUnsyncGet|true +detectorFindUselessControlFlow=FindUselessControlFlow|true +detectorFormatStringChecker=FormatStringChecker|true +detectorHugeSharedStringConstants=HugeSharedStringConstants|true +detectorIDivResultCastToDouble=IDivResultCastToDouble|true +detectorIncompatMask=IncompatMask|true +detectorInconsistentAnnotations=InconsistentAnnotations|true +detectorInefficientMemberAccess=InefficientMemberAccess|false +detectorInefficientToArray=InefficientToArray|true +detectorInfiniteLoop=InfiniteLoop|true +detectorInfiniteRecursiveLoop=InfiniteRecursiveLoop|true +detectorInfiniteRecursiveLoop2=InfiniteRecursiveLoop2|false +detectorInheritanceUnsafeGetResource=InheritanceUnsafeGetResource|true +detectorInitializationChain=InitializationChain|true +detectorInstantiateStaticClass=InstantiateStaticClass|true +detectorInvalidJUnitTest=InvalidJUnitTest|true +detectorIteratorIdioms=IteratorIdioms|true +detectorLazyInit=LazyInit|true +detectorLoadOfKnownNullValue=LoadOfKnownNullValue|true +detectorLostLoggerDueToWeakReference=LostLoggerDueToWeakReference|true +detectorMethodReturnCheck=MethodReturnCheck|true +detectorMultithreadedInstanceAccess=MultithreadedInstanceAccess|true +detectorMutableLock=MutableLock|true +detectorMutableStaticFields=MutableStaticFields|true +detectorNaming=Naming|true +detectorNumberConstructor=NumberConstructor|true +detectorOverridingEqualsNotSymmetrical=OverridingEqualsNotSymmetrical|true +detectorPreferZeroLengthArrays=PreferZeroLengthArrays|true +detectorPublicSemaphores=PublicSemaphores|false +detectorQuestionableBooleanAssignment=QuestionableBooleanAssignment|true +detectorReadOfInstanceFieldInMethodInvokedByConstructorInSuperclass=ReadOfInstanceFieldInMethodInvokedByConstructorInSuperclass|true +detectorReadReturnShouldBeChecked=ReadReturnShouldBeChecked|true +detectorRedundantInterfaces=RedundantInterfaces|true +detectorRepeatedConditionals=RepeatedConditionals|true +detectorRuntimeExceptionCapture=RuntimeExceptionCapture|true +detectorSerializableIdiom=SerializableIdiom|true +detectorStartInConstructor=StartInConstructor|true +detectorStaticCalendarDetector=StaticCalendarDetector|true +detectorStringConcatenation=StringConcatenation|true +detectorSuperfluousInstanceOf=SuperfluousInstanceOf|true +detectorSuspiciousThreadInterrupted=SuspiciousThreadInterrupted|true +detectorSwitchFallthrough=SwitchFallthrough|true +detectorSynchronizeAndNullCheckField=SynchronizeAndNullCheckField|true +detectorSynchronizeOnClassLiteralNotGetClass=SynchronizeOnClassLiteralNotGetClass|true +detectorSynchronizingOnContentsOfFieldToProtectField=SynchronizingOnContentsOfFieldToProtectField|true +detectorURLProblems=URLProblems|true +detectorUncallableMethodOfAnonymousClass=UncallableMethodOfAnonymousClass|true +detectorUnnecessaryMath=UnnecessaryMath|true +detectorUnreadFields=UnreadFields|true +detectorUseObjectEquals=UseObjectEquals|false +detectorUselessSubclassMethod=UselessSubclassMethod|false +detectorVarArgsProblems=VarArgsProblems|true +detectorVolatileUsage=VolatileUsage|true +detectorWaitInLoop=WaitInLoop|true +detectorWrongMapIterator=WrongMapIterator|true +detectorXMLFactoryBypass=XMLFactoryBypass|true +detector_threshold=2 +effort=default +filter_settings=Medium|BAD_PRACTICE,CORRECTNESS,MT_CORRECTNESS,PERFORMANCE,STYLE|false +filter_settings_neg=MALICIOUS_CODE,NOISE,I18N,SECURITY,EXPERIMENTAL| +run_at_full_build=false diff --git a/.project b/.project index 8c4533f0c..8de41c49d 100644 --- a/.project +++ b/.project @@ -15,9 +15,15 @@ + + edu.umd.cs.findbugs.plugin.eclipse.findbugsBuilder + + + org.eclipse.jdt.core.javanature org.maven.ide.eclipse.maven2Nature + edu.umd.cs.findbugs.plugin.eclipse.findbugsNature diff --git a/src/main/java/com/l2jserver/L2JServerRuntime.java b/src/main/java/com/l2jserver/L2JServerRuntime.java new file mode 100644 index 000000000..3c3be8df4 --- /dev/null +++ b/src/main/java/com/l2jserver/L2JServerRuntime.java @@ -0,0 +1,9 @@ +package com.l2jserver; + +import com.l2jserver.service.logging.LoggingService; + +public class L2JServerRuntime { + public LoggingService getLoggingService() { + return null; + } +} diff --git a/src/main/java/com/l2jserver/game/net/Lineage2Connection.java b/src/main/java/com/l2jserver/game/net/Lineage2Connection.java new file mode 100644 index 000000000..9dcc3e67c --- /dev/null +++ b/src/main/java/com/l2jserver/game/net/Lineage2Connection.java @@ -0,0 +1,50 @@ +package com.l2jserver.game.net; + +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.packet.ServerPacket; + +public class Lineage2Connection { + private final Channel channel; + + public Lineage2Connection(Channel channel) { + this.channel = channel; + } + + public Channel getChannel() { + return channel; + } + + public boolean isOpen() { + return channel.isOpen(); + } + + public boolean isConnected() { + return channel.isConnected(); + } + + public ChannelFuture write(ServerPacket message) { + return channel.write(message); + } + + public ChannelFuture disconnect() { + return channel.disconnect(); + } + + public ChannelFuture close() { + return channel.close(); + } + + public Lineage2Decrypter getDecrypter() { + return (Lineage2Decrypter) channel.getPipeline().get( + Lineage2Decrypter.HANDLER_NAME); + } + + public Lineage2Encrypter getEncrypter() { + return (Lineage2Encrypter) channel.getPipeline().get( + Lineage2Encrypter.HANDLER_NAME); + } +} diff --git a/src/main/java/com/l2jserver/game/net/Lineage2PipelineFactory.java b/src/main/java/com/l2jserver/game/net/Lineage2PipelineFactory.java new file mode 100644 index 000000000..b0d429843 --- /dev/null +++ b/src/main/java/com/l2jserver/game/net/Lineage2PipelineFactory.java @@ -0,0 +1,36 @@ +package com.l2jserver.game.net; + +import static org.jboss.netty.channel.Channels.pipeline; + +import org.jboss.netty.channel.ChannelPipeline; +import org.jboss.netty.channel.ChannelPipelineFactory; + +import com.l2jserver.game.net.codec.Lineage2Decoder; +import com.l2jserver.game.net.codec.Lineage2Decrypter; +import com.l2jserver.game.net.codec.Lineage2Encoder; +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.handler.Lineage2PacketHandler; + +public class Lineage2PipelineFactory implements ChannelPipelineFactory { + @Override + public ChannelPipeline getPipeline() throws Exception { + final ChannelPipeline pipeline = pipeline(); + + pipeline.addLast(Lineage2Encrypter.HANDLER_NAME, + new Lineage2Encrypter()); + pipeline.addLast(Lineage2Decrypter.HANDLER_NAME, + new Lineage2Decrypter()); + + pipeline.addLast("header.encoder", new Lineage2Encoder()); + pipeline.addLast("header.decoder", new Lineage2Decoder()); + + pipeline.addLast("packet.writer", new Lineage2PacketWriter()); + pipeline.addLast("packet.reader", new Lineage2PacketReader()); + + pipeline.addLast("packet.handler", new Lineage2PacketHandler()); + + return pipeline; + } +} diff --git a/src/main/java/com/l2jserver/game/net/codec/Lineage2Decoder.java b/src/main/java/com/l2jserver/game/net/codec/Lineage2Decoder.java index 629a57b24..dcd5bc135 100644 --- a/src/main/java/com/l2jserver/game/net/codec/Lineage2Decoder.java +++ b/src/main/java/com/l2jserver/game/net/codec/Lineage2Decoder.java @@ -1,14 +1,29 @@ package com.l2jserver.game.net.codec; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.handler.codec.frame.FrameDecoder; +import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder; -public class Lineage2Decoder extends FrameDecoder { - @Override - protected Object decode(ChannelHandlerContext ctx, Channel channel, - ChannelBuffer buffer) throws Exception { - return null; +public class Lineage2Decoder extends LengthFieldBasedFrameDecoder { + // private static final int HEADER_SIZE = 2; + + public Lineage2Decoder() { + super(16 * 1024, 0, 2); } + + // @Override + // protected Object decode(ChannelHandlerContext ctx, Channel channel, + // ChannelBuffer buffer) throws Exception { + // if (buffer.readableBytes() < 2) + // return null; + // buffer.markReaderIndex(); + // final int pending = buffer.readUnsignedShort() - HEADER_SIZE; + // if(pending == 0) + // return null; + // + // if (buffer.readableBytes() < pending) { + // buffer.resetReaderIndex(); + // return null; + // } + // + // return buffer.slice(buffer.readableBytes(), pending); + // } } diff --git a/src/main/java/com/l2jserver/game/net/codec/Lineage2Decrypter.java b/src/main/java/com/l2jserver/game/net/codec/Lineage2Decrypter.java new file mode 100644 index 000000000..4c1aca746 --- /dev/null +++ b/src/main/java/com/l2jserver/game/net/codec/Lineage2Decrypter.java @@ -0,0 +1,60 @@ +package com.l2jserver.game.net.codec; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.ChannelHandlerContext; +import org.jboss.netty.handler.codec.oneone.OneToOneDecoder; + +public class Lineage2Decrypter extends OneToOneDecoder { + public static final String HANDLER_NAME = "crypto.decoder"; + + private boolean enabled = false; + private final byte[] key = new byte[16]; + + @Override + protected Object decode(ChannelHandlerContext ctx, Channel channel, + Object msg) throws Exception { + if (!(msg instanceof ChannelBuffer)) + return msg; + if (!enabled) + return msg; + final ChannelBuffer buffer = (ChannelBuffer) msg; + + final int offset = buffer.readerIndex(); + final int size = buffer.readableBytes(); + int temp = 0; + for (int i = 0; i < size; i++) { + int temp2 = buffer.getUnsignedByte(offset + i); + buffer.setByte(offset + i, (byte) (temp2 ^ key[i & 15] ^ temp)); + temp = temp2; + } + + int old = key[8] & 0xff; + old |= key[9] << 8 & 0xff00; + old |= key[10] << 0x10 & 0xff0000; + old |= key[11] << 0x18 & 0xff000000; + + old += size; + + key[8] = (byte) (old & 0xff); + key[9] = (byte) (old >> 0x08 & 0xff); + key[10] = (byte) (old >> 0x10 & 0xff); + key[11] = (byte) (old >> 0x18 & 0xff); + + return msg; + } + + public void setKey(byte[] key) { + for (int i = 0; i < 16; i++) { + this.key[i] = key[i]; + } + } + + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } +} diff --git a/src/main/java/com/l2jserver/game/net/codec/Lineage2Encoder.java b/src/main/java/com/l2jserver/game/net/codec/Lineage2Encoder.java index f708d19a1..eba8351e2 100644 --- a/src/main/java/com/l2jserver/game/net/codec/Lineage2Encoder.java +++ b/src/main/java/com/l2jserver/game/net/codec/Lineage2Encoder.java @@ -1,5 +1,9 @@ package com.l2jserver.game.net.codec; -public class Lineage2Encoder { +import org.jboss.netty.handler.codec.frame.LengthFieldPrepender; +public class Lineage2Encoder extends LengthFieldPrepender { + public Lineage2Encoder() { + super(2); + } } diff --git a/src/main/java/com/l2jserver/game/net/codec/Lineage2Encrypter.java b/src/main/java/com/l2jserver/game/net/codec/Lineage2Encrypter.java new file mode 100644 index 000000000..b50744a25 --- /dev/null +++ b/src/main/java/com/l2jserver/game/net/codec/Lineage2Encrypter.java @@ -0,0 +1,58 @@ +package com.l2jserver.game.net.codec; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.ChannelHandlerContext; +import org.jboss.netty.handler.codec.oneone.OneToOneEncoder; + +public class Lineage2Encrypter extends OneToOneEncoder { + public static final String HANDLER_NAME = "crypto.encoder"; + + private boolean enabled = false; + private final byte[] key = new byte[16]; + + @Override + protected Object encode(ChannelHandlerContext ctx, Channel channel, + Object msg) throws Exception { + if (!(msg instanceof ChannelBuffer)) + return msg; + final ChannelBuffer buffer = (ChannelBuffer) msg; + + final int offset = buffer.readerIndex(); + final int size = buffer.readableBytes(); + int temp = 0; + for (int i = 0; i < size; i++) { + int temp2 = buffer.getUnsignedByte(offset + i); + buffer.setByte(offset + i, (byte) (temp2 ^ key[i & 15] ^ temp)); + temp = temp2; + } + + int old = key[8] & 0xff; + old |= key[9] << 8 & 0xff00; + old |= key[10] << 0x10 & 0xff0000; + old |= key[11] << 0x18 & 0xff000000; + + old += size; + + key[8] = (byte) (old & 0xff); + key[9] = (byte) (old >> 0x08 & 0xff); + key[10] = (byte) (old >> 0x10 & 0xff); + key[11] = (byte) (old >> 0x18 & 0xff); + + return msg; + } + + public void setKey(byte[] key) { + for (int i = 0; i < 16; i++) { + this.key[i] = key[i]; + } + } + + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } +} diff --git a/src/main/java/com/l2jserver/game/net/codec/Lineage2PacketReader.java b/src/main/java/com/l2jserver/game/net/codec/Lineage2PacketReader.java new file mode 100644 index 000000000..eea90439d --- /dev/null +++ b/src/main/java/com/l2jserver/game/net/codec/Lineage2PacketReader.java @@ -0,0 +1,38 @@ +package com.l2jserver.game.net.codec; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.ChannelHandlerContext; +import org.jboss.netty.handler.codec.oneone.OneToOneDecoder; + +import com.l2jserver.game.net.packet.ClientPacket; +import com.l2jserver.game.net.packet.client.ProtocolVersionPacket; + +public class Lineage2PacketReader extends OneToOneDecoder { + @Override + protected Object decode(ChannelHandlerContext ctx, Channel channel, + Object msg) throws Exception { + if (!(msg instanceof ChannelBuffer)) + return msg; + final ChannelBuffer buffer = (ChannelBuffer) msg; + final ClientPacket packet = getPacket(buffer); + if (packet == null) + return null; + packet.read(buffer); + return packet; + } + + private ClientPacket getPacket(ChannelBuffer buffer) { + final short opcode = buffer.readUnsignedByte(); + switch (opcode) { + case ProtocolVersionPacket.OPCODE: + return new ProtocolVersionPacket(); + case 0x2b: + return null; + default: + System.out.println("Unk: " + opcode); + break; + } + return null; + } +} diff --git a/src/main/java/com/l2jserver/game/net/codec/Lineage2PacketWriter.java b/src/main/java/com/l2jserver/game/net/codec/Lineage2PacketWriter.java new file mode 100644 index 000000000..c565042aa --- /dev/null +++ b/src/main/java/com/l2jserver/game/net/codec/Lineage2PacketWriter.java @@ -0,0 +1,22 @@ +package com.l2jserver.game.net.codec; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.buffer.ChannelBuffers; +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.ChannelHandlerContext; +import org.jboss.netty.handler.codec.oneone.OneToOneEncoder; + +import com.l2jserver.game.net.packet.ServerPacket; + +public class Lineage2PacketWriter extends OneToOneEncoder { + @Override + protected Object encode(ChannelHandlerContext ctx, Channel channel, + Object msg) throws Exception { + if (!(msg instanceof ServerPacket)) + return msg; + final ChannelBuffer buffer = ChannelBuffers.dynamicBuffer(); + final ServerPacket packet = (ServerPacket) msg; + packet.write(buffer); + return buffer; + } +} diff --git a/src/main/java/com/l2jserver/game/net/handler/Lineage2PacketHandler.java b/src/main/java/com/l2jserver/game/net/handler/Lineage2PacketHandler.java new file mode 100644 index 000000000..82afde18e --- /dev/null +++ b/src/main/java/com/l2jserver/game/net/handler/Lineage2PacketHandler.java @@ -0,0 +1,26 @@ +package com.l2jserver.game.net.handler; + +import org.jboss.netty.channel.ChannelHandlerContext; +import org.jboss.netty.channel.MessageEvent; +import org.jboss.netty.channel.SimpleChannelHandler; + +import com.l2jserver.game.net.packet.ClientPacket; + +public class Lineage2PacketHandler extends SimpleChannelHandler { + @Override + public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) + throws Exception { + final Object msg = e.getMessage(); + if (!(msg instanceof ClientPacket)) + return; + final ClientPacket packet = (ClientPacket) msg; + packet.process(null); + super.messageReceived(ctx, e); + } + + @Override + public void writeRequested(ChannelHandlerContext ctx, MessageEvent e) + throws Exception { + super.writeRequested(ctx, e); + } +} diff --git a/src/main/java/com/l2jserver/game/net/packet/ClientPacket.java b/src/main/java/com/l2jserver/game/net/packet/ClientPacket.java index a0f784da9..977e06341 100644 --- a/src/main/java/com/l2jserver/game/net/packet/ClientPacket.java +++ b/src/main/java/com/l2jserver/game/net/packet/ClientPacket.java @@ -2,6 +2,22 @@ package com.l2jserver.game.net.packet; import org.jboss.netty.buffer.ChannelBuffer; +import com.google.inject.Injector; + public interface ClientPacket extends Packet { + /** + * Read binary data in the {@link ChannelBuffer}. + * + * @param buffer + * the buffer + */ void read(ChannelBuffer buffer); + + /** + * Process the packet + * + * @param injector + * the injector + */ + void process(Injector injector); } diff --git a/src/main/java/com/l2jserver/game/net/packet/client/ProtocolVersionPacket.java b/src/main/java/com/l2jserver/game/net/packet/client/ProtocolVersionPacket.java new file mode 100644 index 000000000..f92c54482 --- /dev/null +++ b/src/main/java/com/l2jserver/game/net/packet/client/ProtocolVersionPacket.java @@ -0,0 +1,30 @@ +package com.l2jserver.game.net.packet.client; + +import org.jboss.netty.buffer.ChannelBuffer; + +import com.google.inject.Injector; +import com.l2jserver.game.net.packet.AbstractClientPacket; + +public class ProtocolVersionPacket extends AbstractClientPacket { + public static final int OPCODE = 0x0e; + + private int version; + + @Override + public void read(ChannelBuffer buffer) { + this.version = buffer.readInt(); + } + + @Override + public void process(Injector injector) { + + } + + public int getVersion() { + return version; + } + + public void setVersion(int version) { + this.version = version; + } +} diff --git a/src/main/java/com/l2jserver/game/net/packet/client/TestPacket.java b/src/main/java/com/l2jserver/game/net/packet/client/TestPacket.java deleted file mode 100644 index 1b0f1dffe..000000000 --- a/src/main/java/com/l2jserver/game/net/packet/client/TestPacket.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.l2jserver.game.net.packet.client; - -import org.jboss.netty.buffer.ChannelBuffer; - -import com.l2jserver.game.net.packet.AbstractClientPacket; - -public class TestPacket extends AbstractClientPacket { - public static final int OPCODE = 0x00; - - @Override - public void read(ChannelBuffer buffer) { - // TODO Auto-generated method stub - - } -} diff --git a/src/main/java/com/l2jserver/model/world/Item.java b/src/main/java/com/l2jserver/model/world/Item.java index a389e8a02..a4059ab54 100644 --- a/src/main/java/com/l2jserver/model/world/Item.java +++ b/src/main/java/com/l2jserver/model/world/Item.java @@ -1,17 +1,27 @@ package com.l2jserver.model.world; +import java.util.List; + import com.l2jserver.model.world.capability.Attackable; import com.l2jserver.model.world.capability.Attacker; import com.l2jserver.model.world.capability.Child; +import com.l2jserver.model.world.capability.Listenable; import com.l2jserver.model.world.capability.Playable; import com.l2jserver.model.world.capability.Spawnable; +import com.l2jserver.model.world.item.ItemEvent; +import com.l2jserver.model.world.item.ItemListener; import com.l2jserver.util.Coordinate; +import com.l2jserver.util.factory.CollectionFactory; public class Item extends AbstractObject implements Playable, Spawnable, - Attacker, Attackable, Child { + Attacker, Attackable, Child, + Listenable { + private final List listeners = CollectionFactory + .newList(ItemListener.class); + @Override public void spawn(Coordinate coordinate) { - + } @Override @@ -26,6 +36,23 @@ public class Item extends AbstractObject implements Playable, Spawnable, } + @Override + public void addListener(ItemListener listener) { + listeners.add(listener); + } + + @Override + public void removeListener(ItemListener listener) { + listeners.remove(listener); + } + + @Override + public void dispatch(ItemEvent e) { + for (final ItemListener listener : listeners) { + listener.dispatch(e); + } + } + @Override public boolean isSpawned() { // TODO Auto-generated method stub diff --git a/src/main/java/com/l2jserver/model/world/Player.java b/src/main/java/com/l2jserver/model/world/Player.java index 2d3f87f43..7592bb620 100644 --- a/src/main/java/com/l2jserver/model/world/Player.java +++ b/src/main/java/com/l2jserver/model/world/Player.java @@ -14,6 +14,7 @@ import com.l2jserver.model.world.capability.Spawnable; import com.l2jserver.model.world.player.PlayerEvent; import com.l2jserver.model.world.player.PlayerListener; import com.l2jserver.util.Coordinate; +import com.l2jserver.util.factory.CollectionFactory; /** * {@link Player} is any object that can be controlled by the player. The most @@ -24,6 +25,9 @@ import com.l2jserver.util.Coordinate; public abstract class Player extends AbstractObject implements Playable, Spawnable, Attacker, Attackable, Listenable, Caster, Parent { + private final List listeners = CollectionFactory + .newList(PlayerListener.class); + @Override public void spawn(Coordinate coordinate) { @@ -43,37 +47,25 @@ public abstract class Player extends AbstractObject implements Playable, @Override public void addListener(PlayerListener listener) { - // TODO Auto-generated method stub - + listeners.add(listener); } @Override public void removeListener(PlayerListener listener) { - // TODO Auto-generated method stub - - } - - @Override - public List getListeners() { - // TODO Auto-generated method stub - return null; - } - - @Override - public boolean support(Class eventType) { - return eventType.isAssignableFrom(PlayerEvent.class); - } - - @Override - public Coordinate getPosition() { - // TODO Auto-generated method stub - return null; + listeners.remove(listener); } @Override public void dispatch(PlayerEvent e) { - // TODO Auto-generated method stub + for (final PlayerListener listener : listeners) { + listener.dispatch(e); + } + } + @Override + public Coordinate getPosition() { + // TODO Auto-generated method stub + return null; } @Override diff --git a/src/main/java/com/l2jserver/model/world/World.java b/src/main/java/com/l2jserver/model/world/World.java new file mode 100644 index 000000000..2e91830c8 --- /dev/null +++ b/src/main/java/com/l2jserver/model/world/World.java @@ -0,0 +1,52 @@ +package com.l2jserver.model.world; + +import java.util.Iterator; +import java.util.Set; + +import com.l2jserver.model.world.event.WorldEventDispatcher; +import com.l2jserver.model.world.filter.WorldObjectFilter; +import com.l2jserver.model.world.iterator.FilterIterator; +import com.l2jserver.util.factory.CollectionFactory; + +public class World implements Iterable { + private final Set objects = CollectionFactory + .newSet(WorldObject.class); + private final WorldEventDispatcher dispatcher = new WorldEventDispatcher( + this); + + public void add(WorldObject object) { + objects.add(object); + } + + public void remove(WorldObject object) { + objects.remove(object); + } + + public boolean contains(WorldObject object) { + return objects.contains(object); + } + + public WorldEventDispatcher getDispatcher() { + return dispatcher; + } + + @Override + public Iterator iterator() { + return objects.iterator(); + } + + public Iterator iterator( + final WorldObjectFilter filter) { + return new FilterIterator(filter, objects.iterator()); + } + + public Iterable iterable( + final WorldObjectFilter filter) { + return new Iterable() { + @Override + public Iterator iterator() { + return new FilterIterator(filter, objects.iterator()); + } + }; + } +} diff --git a/src/main/java/com/l2jserver/model/world/capability/Listenable.java b/src/main/java/com/l2jserver/model/world/capability/Listenable.java index fdce1ea61..5fb266e28 100644 --- a/src/main/java/com/l2jserver/model/world/capability/Listenable.java +++ b/src/main/java/com/l2jserver/model/world/capability/Listenable.java @@ -1,7 +1,5 @@ package com.l2jserver.model.world.capability; -import java.util.List; - import com.l2jserver.model.world.AbstractObject; import com.l2jserver.model.world.event.WorldEvent; import com.l2jserver.model.world.event.WorldListener; @@ -19,13 +17,27 @@ import com.l2jserver.model.world.event.WorldListener; */ public interface Listenable, E extends WorldEvent> extends WorldCapability { + /** + * Adds a new listener + * + * @param listener + * the listener + */ void addListener(L listener); + /** + * Removes an listener + * + * @param listener + * the listener + */ void removeListener(L listener); - List getListeners(); - - boolean support(Class eventType); - + /** + * Don't use this method directly. It is called by the event dispatcher. + * + * @param e + * the event + */ void dispatch(E e); } diff --git a/src/main/java/com/l2jserver/model/world/event/WorldEvent.java b/src/main/java/com/l2jserver/model/world/event/WorldEvent.java index e7c2c4713..92e3412ff 100644 --- a/src/main/java/com/l2jserver/model/world/event/WorldEvent.java +++ b/src/main/java/com/l2jserver/model/world/event/WorldEvent.java @@ -1,5 +1,12 @@ package com.l2jserver.model.world.event; -public interface WorldEvent { +import com.l2jserver.model.world.WorldObject; +public interface WorldEvent { + WorldObject getObject(); + + /** + * Dispatch this event to all the objects + */ + void dispatch(); } diff --git a/src/main/java/com/l2jserver/model/world/event/WorldEventDispatcher.java b/src/main/java/com/l2jserver/model/world/event/WorldEventDispatcher.java new file mode 100644 index 000000000..7e39fb60f --- /dev/null +++ b/src/main/java/com/l2jserver/model/world/event/WorldEventDispatcher.java @@ -0,0 +1,16 @@ +package com.l2jserver.model.world.event; + +import com.l2jserver.model.world.World; + +public class WorldEventDispatcher { + private final World world; + + public WorldEventDispatcher(World world) { + this.world = world; + } + + public void dispatch(WorldEvent event) { + //TODO implement threaded model + event.dispatch(); + } +} diff --git a/src/main/java/com/l2jserver/model/world/event/WorldListener.java b/src/main/java/com/l2jserver/model/world/event/WorldListener.java index 95f533a3d..61302deab 100644 --- a/src/main/java/com/l2jserver/model/world/event/WorldListener.java +++ b/src/main/java/com/l2jserver/model/world/event/WorldListener.java @@ -1,5 +1,20 @@ package com.l2jserver.model.world.event; +/** + * This is the most abstract listener for the listening engine. + * + * @author Rogiel + * + * @param + * the received event type + */ public interface WorldListener { - void onAction(E e); + /** + * Once the event call is dispatched, the listener WILL NOT be + * removed. You must manually remove it from the event object. + * + * @param e + * the event + */ + void dispatch(E e); } diff --git a/src/main/java/com/l2jserver/model/world/filter/AndFilter.java b/src/main/java/com/l2jserver/model/world/filter/AndFilter.java index 1f7907217..b610a9cb5 100644 --- a/src/main/java/com/l2jserver/model/world/filter/AndFilter.java +++ b/src/main/java/com/l2jserver/model/world/filter/AndFilter.java @@ -2,16 +2,16 @@ package com.l2jserver.model.world.filter; import com.l2jserver.model.world.WorldObject; -public class AndFilter implements WorldFilter { - private WorldFilter[] filters; +public class AndFilter implements WorldObjectFilter { + private WorldObjectFilter[] filters; - public AndFilter(WorldFilter... filters) { + public AndFilter(WorldObjectFilter... filters) { this.filters = filters; } @Override public boolean accept(O object) { - for(final WorldFilter filter : filters) { + for(final WorldObjectFilter filter : filters) { if(!filter.accept(object)) return false; } diff --git a/src/main/java/com/l2jserver/model/world/filter/NotFilter.java b/src/main/java/com/l2jserver/model/world/filter/NotFilter.java index b5fcec9b4..44fafcd5c 100644 --- a/src/main/java/com/l2jserver/model/world/filter/NotFilter.java +++ b/src/main/java/com/l2jserver/model/world/filter/NotFilter.java @@ -2,10 +2,10 @@ package com.l2jserver.model.world.filter; import com.l2jserver.model.world.WorldObject; -public class NotFilter implements WorldFilter { - private WorldFilter filter; +public class NotFilter implements WorldObjectFilter { + private WorldObjectFilter filter; - public NotFilter(WorldFilter filter) { + public NotFilter(WorldObjectFilter filter) { this.filter = filter; } diff --git a/src/main/java/com/l2jserver/model/world/filter/OrFilter.java b/src/main/java/com/l2jserver/model/world/filter/OrFilter.java index 6ca2459bb..0d85ca9dc 100644 --- a/src/main/java/com/l2jserver/model/world/filter/OrFilter.java +++ b/src/main/java/com/l2jserver/model/world/filter/OrFilter.java @@ -2,16 +2,16 @@ package com.l2jserver.model.world.filter; import com.l2jserver.model.world.WorldObject; -public class OrFilter implements WorldFilter { - private WorldFilter[] filters; +public class OrFilter implements WorldObjectFilter { + private WorldObjectFilter[] filters; - public OrFilter(WorldFilter... filters) { + public OrFilter(WorldObjectFilter... filters) { this.filters = filters; } @Override public boolean accept(O object) { - for(final WorldFilter filter : filters) { + for(final WorldObjectFilter filter : filters) { if(filter.accept(object)) return true; } diff --git a/src/main/java/com/l2jserver/model/world/filter/WorldFilters.java b/src/main/java/com/l2jserver/model/world/filter/WorldFilters.java index db9cd3302..0104df905 100644 --- a/src/main/java/com/l2jserver/model/world/filter/WorldFilters.java +++ b/src/main/java/com/l2jserver/model/world/filter/WorldFilters.java @@ -3,18 +3,18 @@ package com.l2jserver.model.world.filter; import com.l2jserver.model.world.WorldObject; public final class WorldFilters { - public static final WorldFilter and( - WorldFilter... filters) { + public static final WorldObjectFilter and( + WorldObjectFilter... filters) { return new AndFilter(filters); } - public static final WorldFilter or( - WorldFilter... filters) { + public static final WorldObjectFilter or( + WorldObjectFilter... filters) { return new OrFilter(filters); } - public static final WorldFilter notf( - WorldFilter filter) { + public static final WorldObjectFilter notf( + WorldObjectFilter filter) { return new NotFilter(filter); } } diff --git a/src/main/java/com/l2jserver/model/world/filter/WorldFilter.java b/src/main/java/com/l2jserver/model/world/filter/WorldObjectFilter.java similarity index 86% rename from src/main/java/com/l2jserver/model/world/filter/WorldFilter.java rename to src/main/java/com/l2jserver/model/world/filter/WorldObjectFilter.java index 04710a610..5957eff12 100644 --- a/src/main/java/com/l2jserver/model/world/filter/WorldFilter.java +++ b/src/main/java/com/l2jserver/model/world/filter/WorldObjectFilter.java @@ -7,7 +7,7 @@ import com.l2jserver.model.world.WorldObject; * * @author Rogiel */ -public interface WorldFilter { +public interface WorldObjectFilter { /** * Test if object matches the filter requirements * diff --git a/src/main/java/com/l2jserver/model/world/filter/impl/IDFilter.java b/src/main/java/com/l2jserver/model/world/filter/impl/IDFilter.java index 90b0d5132..0293848e7 100644 --- a/src/main/java/com/l2jserver/model/world/filter/impl/IDFilter.java +++ b/src/main/java/com/l2jserver/model/world/filter/impl/IDFilter.java @@ -2,9 +2,9 @@ package com.l2jserver.model.world.filter.impl; import com.l2jserver.model.id.ID; import com.l2jserver.model.world.capability.Positionable; -import com.l2jserver.model.world.filter.WorldFilter; +import com.l2jserver.model.world.filter.WorldObjectFilter; -public class IDFilter implements WorldFilter { +public class IDFilter implements WorldObjectFilter { private final ID id; public IDFilter(final ID id) { diff --git a/src/main/java/com/l2jserver/model/world/filter/impl/InstanceFilter.java b/src/main/java/com/l2jserver/model/world/filter/impl/InstanceFilter.java new file mode 100644 index 000000000..32f919fed --- /dev/null +++ b/src/main/java/com/l2jserver/model/world/filter/impl/InstanceFilter.java @@ -0,0 +1,19 @@ +package com.l2jserver.model.world.filter.impl; + +import com.l2jserver.model.world.WorldObject; +import com.l2jserver.model.world.filter.WorldObjectFilter; + +public class InstanceFilter implements WorldObjectFilter { + private final Class type; + + public InstanceFilter(Class instance) { + this.type = instance; + } + + @Override + public boolean accept(T other) { + if (other == null) + return false; + return type.isInstance(other); + } +} diff --git a/src/main/java/com/l2jserver/model/world/filter/impl/RangeFilter.java b/src/main/java/com/l2jserver/model/world/filter/impl/RangeFilter.java index b240fa84d..6fc2136e3 100644 --- a/src/main/java/com/l2jserver/model/world/filter/impl/RangeFilter.java +++ b/src/main/java/com/l2jserver/model/world/filter/impl/RangeFilter.java @@ -1,10 +1,10 @@ package com.l2jserver.model.world.filter.impl; import com.l2jserver.model.world.capability.Positionable; -import com.l2jserver.model.world.filter.WorldFilter; +import com.l2jserver.model.world.filter.WorldObjectFilter; import com.l2jserver.util.Coordinate; -public class RangeFilter implements WorldFilter { +public class RangeFilter implements WorldObjectFilter { private final Coordinate coordinate; private final int range; diff --git a/src/main/java/com/l2jserver/model/world/item/ItemDropEvent.java b/src/main/java/com/l2jserver/model/world/item/ItemDropEvent.java new file mode 100644 index 000000000..87332265c --- /dev/null +++ b/src/main/java/com/l2jserver/model/world/item/ItemDropEvent.java @@ -0,0 +1,38 @@ +package com.l2jserver.model.world.item; + +import com.l2jserver.model.world.Item; +import com.l2jserver.model.world.Player; +import com.l2jserver.model.world.WorldObject; +import com.l2jserver.model.world.player.PlayerEvent; + +public class ItemDropEvent implements ItemEvent, PlayerEvent { + private final Player player; + private final Item item; + + public ItemDropEvent(Player player, Item item) { + this.player = player; + this.item = item; + } + + @Override + public WorldObject getObject() { + return item; + } + + @Override + public Player getPlayer() { + return player; + } + + @Override + public Item getItem() { + return item; + } + + @Override + public void dispatch() { + item.dispatch(this); + if (player != null) + player.dispatch(this); + } +} diff --git a/src/main/java/com/l2jserver/model/world/iterator/FilterIterator.java b/src/main/java/com/l2jserver/model/world/iterator/FilterIterator.java new file mode 100644 index 000000000..5829bf3c6 --- /dev/null +++ b/src/main/java/com/l2jserver/model/world/iterator/FilterIterator.java @@ -0,0 +1,55 @@ +package com.l2jserver.model.world.iterator; + +import java.util.Iterator; + +import com.l2jserver.model.world.WorldObject; +import com.l2jserver.model.world.filter.WorldObjectFilter; + +public class FilterIterator implements Iterator { + private final Iterator objects; + private final WorldObjectFilter filter; + + private O selected; + + public FilterIterator(final WorldObjectFilter filter, + Iterator objects) { + this.filter = filter; + this.objects = objects; + } + + @Override + public boolean hasNext() { + O next = findNext(); + return (next != null); + } + + @Override + public O next() { + try { + return findNext(); + } finally { + selected = null; + } + } + + @Override + public void remove() { + } + + public O findNext() { + if (selected != null) + return selected; + while (objects.hasNext()) { + try { + @SuppressWarnings("unchecked") + final O object = (O) objects.next(); + if (filter.accept(object)) { + selected = object; + return selected; + } + } catch (ClassCastException e) { + } + } + return null; + } +} diff --git a/src/main/java/com/l2jserver/model/world/player/PlayerSpawnEvent.java b/src/main/java/com/l2jserver/model/world/player/PlayerSpawnEvent.java index 9c7532c07..27606bdbe 100644 --- a/src/main/java/com/l2jserver/model/world/player/PlayerSpawnEvent.java +++ b/src/main/java/com/l2jserver/model/world/player/PlayerSpawnEvent.java @@ -20,4 +20,10 @@ public class PlayerSpawnEvent implements PlayerEvent, SpawnEvent { public Player getPlayer() { return player; } + + @Override + public void dispatch() { + if(player != null) + player.dispatch(this); + } } diff --git a/src/main/java/com/l2jserver/model/world/player/TestEvent.java b/src/main/java/com/l2jserver/model/world/player/TestEvent.java new file mode 100644 index 000000000..5035a9280 --- /dev/null +++ b/src/main/java/com/l2jserver/model/world/player/TestEvent.java @@ -0,0 +1,6 @@ +package com.l2jserver.model.world.player; + +import com.l2jserver.model.world.event.WorldEvent; + +public interface TestEvent extends WorldEvent { +} diff --git a/src/main/java/com/l2jserver/service/game/world/WorldEventDispatcher.java b/src/main/java/com/l2jserver/service/game/world/WorldEventDispatcher.java deleted file mode 100644 index 32f62674f..000000000 --- a/src/main/java/com/l2jserver/service/game/world/WorldEventDispatcher.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.l2jserver.service.game.world; - -import com.l2jserver.model.world.AbstractObject; -import com.l2jserver.model.world.event.WorldEvent; - -public interface WorldEventDispatcher { - void dispatch(AbstractObject object, WorldEvent event); -} diff --git a/src/main/java/com/l2jserver/service/game/world/WorldServiceImpl.java b/src/main/java/com/l2jserver/service/game/world/WorldServiceImpl.java index 534ca424f..07ed0f854 100644 --- a/src/main/java/com/l2jserver/service/game/world/WorldServiceImpl.java +++ b/src/main/java/com/l2jserver/service/game/world/WorldServiceImpl.java @@ -1,16 +1,13 @@ package com.l2jserver.service.game.world; import java.util.Iterator; -import java.util.Set; import com.l2jserver.model.world.WorldObject; -import com.l2jserver.model.world.filter.WorldFilter; +import com.l2jserver.model.world.filter.WorldObjectFilter; import com.l2jserver.service.ServiceStartException; import com.l2jserver.service.ServiceStopException; public class WorldServiceImpl implements WorldService { - private Set objects; - @Override public void start() throws ServiceStartException { // TODO Auto-generated method stub @@ -31,14 +28,15 @@ public class WorldServiceImpl implements WorldService { @Override public Iterator iterator() { - return objects.iterator(); - } - - public Iterator iterator(WorldFilter filter) { - //return objects.iterator(); + // return objects.iterator(); return null; } - + + public Iterator iterator(WorldObjectFilter filter) { + // return objects.iterator(); + return null; + } + @Override public void stop() throws ServiceStopException { // TODO Auto-generated method stub diff --git a/src/main/java/com/l2jserver/service/network/NettyNetworkService.java b/src/main/java/com/l2jserver/service/network/NettyNetworkService.java index 536341772..6d94216c5 100644 --- a/src/main/java/com/l2jserver/service/network/NettyNetworkService.java +++ b/src/main/java/com/l2jserver/service/network/NettyNetworkService.java @@ -1,10 +1,18 @@ package com.l2jserver.service.network; +import java.util.concurrent.Executors; + +import org.jboss.netty.bootstrap.ServerBootstrap; +import org.jboss.netty.channel.ServerChannel; +import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory; + import com.google.inject.Inject; import com.l2jserver.service.configuration.ConfigurationService; public class NettyNetworkService implements NetworkService { private final NetworkConfiguration config; + private ServerBootstrap server; + private ServerChannel channel; @Inject public NettyNetworkService(ConfigurationService configService) { @@ -13,11 +21,19 @@ public class NettyNetworkService implements NetworkService { @Override public void start() { - + server = new ServerBootstrap(new NioServerSocketChannelFactory( + Executors.newCachedThreadPool(), + Executors.newCachedThreadPool())); + channel = (ServerChannel) server.bind(config.getListenAddress()); } @Override public void stop() { - + try { + channel.close().awaitUninterruptibly(); + } finally { + server = null; + channel = null; + } } } diff --git a/src/test/java/com/l2jserver/model/world/WorldTest.java b/src/test/java/com/l2jserver/model/world/WorldTest.java new file mode 100644 index 000000000..959ae9dff --- /dev/null +++ b/src/test/java/com/l2jserver/model/world/WorldTest.java @@ -0,0 +1,130 @@ +package com.l2jserver.model.world; + +import java.util.concurrent.atomic.AtomicBoolean; + +import junit.framework.Assert; + +import org.junit.Test; + +import com.l2jserver.model.world.filter.impl.InstanceFilter; +import com.l2jserver.model.world.item.ItemDropEvent; +import com.l2jserver.model.world.item.ItemEvent; +import com.l2jserver.model.world.item.ItemListener; +import com.l2jserver.model.world.player.PlayerEvent; +import com.l2jserver.model.world.player.PlayerListener; +import com.l2jserver.model.world.player.PlayerSpawnEvent; + +public class WorldTest { + @Test + public void testAdd() { + final World world = new World(); + final Character character = new Character(); + world.add(character); + } + + @Test + public void testRemove() { + final World world = new World(); + final Character character = new Character(); + world.add(character); + world.remove(character); + } + + @Test + public void testContains() { + final World world = new World(); + final Character character = new Character(); + world.add(character); + Assert.assertTrue(world.contains(character)); + } + + @Test + public void testIterator() { + final World world = new World(); + final Character character1 = new Character(); + final Character character2 = new Character(); + final Item item1 = new Item(); + world.add(character1); + world.add(character2); + world.add(item1); + + for (final WorldObject o : world) { + Assert.assertNotNull(o); + } + final Iterable it = world.iterable(new InstanceFilter( + Item.class)); + for (final WorldObject o : it) { + Assert.assertNotNull(o); + } + } + + @Test + public void testListeners1() { + final World world = new World(); + final Character character1 = new Character(); + final Character character2 = new Character(); + final Item item1 = new Item(); + world.add(character1); + world.add(character2); + world.add(item1); + + final AtomicBoolean bool = new AtomicBoolean(); + Assert.assertFalse(bool.get()); + character1.addListener(new PlayerListener() { + @Override + public void dispatch(PlayerEvent e) { + bool.set(true); + e.getPlayer().removeListener(this); + } + }); + character1.addListener(new PlayerListener() { + @Override + public void dispatch(PlayerEvent e) { + // bool.set(true); + } + }); + world.getDispatcher().dispatch(new PlayerSpawnEvent(character1)); + Assert.assertTrue(bool.get()); + + bool.set(false); + + world.getDispatcher().dispatch(new PlayerSpawnEvent(character1)); + Assert.assertFalse(bool.get()); + } + + @Test + public void testListeners2() { + final World world = new World(); + final Character character1 = new Character(); + final Character character2 = new Character(); + final Item item1 = new Item(); + final Item item2 = new Item(); + world.add(character1); + world.add(character2); + world.add(item1); + world.add(item2); + + final AtomicBoolean bool1 = new AtomicBoolean(); + final AtomicBoolean bool2 = new AtomicBoolean(); + + Assert.assertFalse(bool1.get()); + Assert.assertFalse(bool2.get()); + + character1.addListener(new PlayerListener() { + @Override + public void dispatch(PlayerEvent e) { + bool1.set(true); + } + }); + item1.addListener(new ItemListener() { + @Override + public void dispatch(ItemEvent e) { + bool2.set(true); + } + }); + + world.getDispatcher().dispatch(new ItemDropEvent(character1, item1)); + Assert.assertTrue(bool1.get()); + Assert.assertTrue(bool2.get()); + } +}