00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 package com.realtime.crossfire.jxclient.server.crossfire;
00023
00024 import com.realtime.crossfire.jxclient.map.Location;
00025 import com.realtime.crossfire.jxclient.server.server.ReceivedPacketListener;
00026 import com.realtime.crossfire.jxclient.util.EventListenerList2;
00027 import java.nio.ByteBuffer;
00028 import java.nio.charset.Charset;
00029 import org.jetbrains.annotations.NotNull;
00030 import org.jetbrains.annotations.Nullable;
00031
00037 public abstract class AbstractCrossfireServerConnection implements CrossfireServerConnection {
00038
00043 @NotNull
00044 protected static final Charset UTF8 = Charset.forName("UTF-8");
00045
00049 @NotNull
00050 private final Model model;
00051
00056 @NotNull
00057 private final EventListenerList2<CrossfireDrawinfoListener> drawinfoListeners = new EventListenerList2<CrossfireDrawinfoListener>(CrossfireDrawinfoListener.class);
00058
00063 @NotNull
00064 private final EventListenerList2<CrossfireDrawextinfoListener> drawextinfoListeners = new EventListenerList2<CrossfireDrawextinfoListener>(CrossfireDrawextinfoListener.class);
00065
00070 @NotNull
00071 private final EventListenerList2<CrossfireQueryListener> queryListeners = new EventListenerList2<CrossfireQueryListener>(CrossfireQueryListener.class);
00072
00077 @NotNull
00078 private final EventListenerList2<CrossfireMagicmapListener> magicmapListeners = new EventListenerList2<CrossfireMagicmapListener>(CrossfireMagicmapListener.class);
00079
00084 @NotNull
00085 private final EventListenerList2<CrossfireUpdateItemListener> crossfireUpdateItemListeners = new EventListenerList2<CrossfireUpdateItemListener>(CrossfireUpdateItemListener.class);
00086
00091 @Nullable
00092 protected CrossfireUpdateMapListener crossfireUpdateMapListener;
00093
00097 @NotNull
00098 private final EventListenerList2<CrossfireTickListener> crossfireTickListeners = new EventListenerList2<CrossfireTickListener>(CrossfireTickListener.class);
00099
00104 @NotNull
00105 private final EventListenerList2<CrossfireSoundListener> crossfireSoundListeners = new EventListenerList2<CrossfireSoundListener>(CrossfireSoundListener.class);
00106
00111 @NotNull
00112 private final EventListenerList2<CrossfireMusicListener> crossfireMusicListeners = new EventListenerList2<CrossfireMusicListener>(CrossfireMusicListener.class);
00113
00117 @NotNull
00118 private final EventListenerList2<CrossfireComcListener> crossfireComcListeners = new EventListenerList2<CrossfireComcListener>(CrossfireComcListener.class);
00119
00123 @NotNull
00124 private final EventListenerList2<CrossfireFaceListener> crossfireFaceListeners = new EventListenerList2<CrossfireFaceListener>(CrossfireFaceListener.class);
00125
00130 @NotNull
00131 private final EventListenerList2<ReceivedPacketListener> receivedPacketListeners = new EventListenerList2<ReceivedPacketListener>(ReceivedPacketListener.class);
00132
00136 @NotNull
00137 private final EventListenerList2<SentReplyListener> sentReplyListeners = new EventListenerList2<SentReplyListener>(SentReplyListener.class);
00138
00143 @NotNull
00144 private final EventListenerList2<CrossfirePickupListener> crossfirePickupListeners = new EventListenerList2<CrossfirePickupListener>(CrossfirePickupListener.class);
00145
00150 @NotNull
00151 private final EventListenerList2<CrossfireAccountListener> crossfireAccountListeners = new EventListenerList2<CrossfireAccountListener>(CrossfireAccountListener.class);
00152
00157 @NotNull
00158 private final EventListenerList2<CrossfireFailureListener> crossfireFailureListeners = new EventListenerList2<CrossfireFailureListener>(CrossfireFailureListener.class);
00159
00164 protected AbstractCrossfireServerConnection(@NotNull final Model model) {
00165 this.model = model;
00166 }
00167
00171 @Override
00172 public void addCrossfireDrawinfoListener(@NotNull final CrossfireDrawinfoListener listener) {
00173 drawinfoListeners.add(listener);
00174 }
00175
00179 @Override
00180 public void removeCrossfireDrawinfoListener(@NotNull final CrossfireDrawinfoListener listener) {
00181 drawinfoListeners.remove(listener);
00182 }
00183
00187 @Override
00188 public void addCrossfireDrawextinfoListener(@NotNull final CrossfireDrawextinfoListener listener) {
00189 drawextinfoListeners.add(listener);
00190 }
00191
00195 @Override
00196 public void removeCrossfireDrawextinfoListener(@NotNull final CrossfireDrawextinfoListener listener) {
00197 drawextinfoListeners.remove(listener);
00198 }
00199
00203 @Override
00204 public void addCrossfireQueryListener(@NotNull final CrossfireQueryListener listener) {
00205 queryListeners.add(listener);
00206 }
00207
00211 @Override
00212 public void removeCrossfireQueryListener(@NotNull final CrossfireQueryListener listener) {
00213 queryListeners.remove(listener);
00214 }
00215
00219 @Override
00220 public void addCrossfireMagicmapListener(@NotNull final CrossfireMagicmapListener listener) {
00221 magicmapListeners.add(listener);
00222 }
00223
00227 @Override
00228 public void removeCrossfireMagicmapListener(@NotNull final CrossfireMagicmapListener listener) {
00229 magicmapListeners.remove(listener);
00230 }
00231
00235 @Override
00236 public void addCrossfireUpdateItemListener(@NotNull final CrossfireUpdateItemListener crossfireUpdateItemListener) {
00237 crossfireUpdateItemListeners.add(crossfireUpdateItemListener);
00238 }
00239
00243 @Override
00244 public void removeCrossfireUpdateItemListener(@NotNull final CrossfireUpdateItemListener crossfireUpdateItemListener) {
00245 crossfireUpdateItemListeners.remove(crossfireUpdateItemListener);
00246 }
00247
00251 @Override
00252 public void setCrossfireUpdateMapListener(@Nullable final CrossfireUpdateMapListener listener) {
00253 if (listener != null && crossfireUpdateMapListener != null) {
00254 throw new IllegalStateException();
00255 }
00256 crossfireUpdateMapListener = listener;
00257 }
00258
00262 @Override
00263 public void addCrossfireTickListener(@NotNull final CrossfireTickListener listener) {
00264 crossfireTickListeners.add(listener);
00265 }
00266
00270 @Override
00271 public void addCrossfireSoundListener(@NotNull final CrossfireSoundListener listener) {
00272 crossfireSoundListeners.add(listener);
00273 }
00274
00278 @Override
00279 public void addCrossfireMusicListener(@NotNull final CrossfireMusicListener listener) {
00280 crossfireMusicListeners.add(listener);
00281 }
00282
00286 @Override
00287 public void addCrossfireComcListener(@NotNull final CrossfireComcListener listener) {
00288 crossfireComcListeners.add(listener);
00289 }
00290
00294 @Override
00295 public void addCrossfireFaceListener(@NotNull final CrossfireFaceListener listener) {
00296 crossfireFaceListeners.add(listener);
00297 }
00298
00302 @Override
00303 public void addPacketWatcherListener(@NotNull final ReceivedPacketListener listener) {
00304 receivedPacketListeners.add(listener);
00305 }
00306
00310 @Override
00311 public void addCrossfireAccountListener(@NotNull final CrossfireAccountListener listener) {
00312 crossfireAccountListeners.add(listener);
00313 }
00314
00318 @Override
00319 public void removeCrossfireAccountListener(@NotNull final CrossfireAccountListener listener) {
00320 crossfireAccountListeners.remove(listener);
00321 }
00322
00326 @Override
00327 public void removePacketWatcherListener(@NotNull final ReceivedPacketListener listener) {
00328 receivedPacketListeners.remove(listener);
00329 }
00330
00334 @Override
00335 public void addSentReplyListener(@NotNull final SentReplyListener listener) {
00336 sentReplyListeners.add(listener);
00337 }
00338
00342 @Override
00343 public void removeSentReplyListener(@NotNull final SentReplyListener listener) {
00344 sentReplyListeners.remove(listener);
00345 }
00346
00350 @Override
00351 public void addCrossfirePickupListener(@NotNull final CrossfirePickupListener listener) {
00352 crossfirePickupListeners.add(listener);
00353 }
00354
00358 @Override
00359 public void removeCrossfirePickupListener(@NotNull final CrossfirePickupListener listener) {
00360 crossfirePickupListeners.remove(listener);
00361 }
00362
00366 @Override
00367 public void addCrossfireFailureListener(@NotNull final CrossfireFailureListener listener) {
00368 crossfireFailureListeners.add(listener);
00369 }
00370
00374 @Override
00375 public void removeCrossfireFailureListener(@NotNull final CrossfireFailureListener listener) {
00376 crossfireFailureListeners.remove(listener);
00377 }
00378
00379 protected void fireMapClear(final int x, final int y) {
00380 assert crossfireUpdateMapListener != null;
00381 crossfireUpdateMapListener.mapClear(x, y);
00382 }
00383
00384 protected void fireMapDarkness(final int x, final int y, final int darkness) {
00385 assert crossfireUpdateMapListener != null;
00386 crossfireUpdateMapListener.mapDarkness(x, y, darkness);
00387 }
00388
00389 protected void fireMapFace(@NotNull final Location location, final int face) {
00390 assert crossfireUpdateMapListener != null;
00391 crossfireUpdateMapListener.mapFace(location, face);
00392 }
00393
00394 protected void fireMapAnimation(@NotNull final Location location, final int animationNum, final int animationType) {
00395 assert crossfireUpdateMapListener != null;
00396 crossfireUpdateMapListener.mapAnimation(location, animationNum, animationType);
00397 }
00398
00399 protected void fireMapSmooth(@NotNull final Location location, final int smooth) {
00400 assert crossfireUpdateMapListener != null;
00401 crossfireUpdateMapListener.mapSmooth(location, smooth);
00402 }
00403
00404 protected void fireMapAnimationSpeed(@NotNull final Location location, final int animSpeed) {
00405 assert crossfireUpdateMapListener != null;
00406 crossfireUpdateMapListener.mapAnimationSpeed(location, animSpeed);
00407 }
00408
00409 protected void fireManageAccount() {
00410 for (final CrossfireAccountListener crossfireAccountListener : crossfireAccountListeners.getListeners()) {
00411 crossfireAccountListener.manageAccount();
00412 }
00413 }
00414
00415 protected void fireStartAccountList(@NotNull final String accountName) {
00416 for (final CrossfireAccountListener crossfireAccountListener : crossfireAccountListeners.getListeners()) {
00417 crossfireAccountListener.startAccountList(accountName);
00418 }
00419 }
00420
00421 protected void fireAddAccount(@NotNull final String name, @NotNull final String characterClass, @NotNull final String race, @NotNull final String face, @NotNull final String party, @NotNull final String map, final int level, final int faceNumber) {
00422 for (final CrossfireAccountListener crossfireAccountListener : crossfireAccountListeners.getListeners()) {
00423 crossfireAccountListener.addAccount(name, characterClass, race, face, party, map, level, faceNumber);
00424 }
00425 }
00426
00427 protected void fireEndAccountList() {
00428 for (final CrossfireAccountListener crossfireAccountListener : crossfireAccountListeners.getListeners()) {
00429 crossfireAccountListener.endAccountList();
00430 }
00431 }
00432
00433 protected void fireStartPlaying() {
00434 for (final CrossfireAccountListener crossfireAccountListener : crossfireAccountListeners.getListeners()) {
00435 crossfireAccountListener.startPlaying();
00436 }
00437 }
00438
00439 protected void fireAddAnimation(final int animation, final int flags, @NotNull final int[] faces) {
00440 if (crossfireUpdateMapListener != null) {
00441 crossfireUpdateMapListener.addAnimation(animation, flags, faces);
00442 }
00443 }
00444
00445 protected void fireCommandComcReceived(final int packetNo, final int time) {
00446 for (final CrossfireComcListener listener : crossfireComcListeners.getListeners()) {
00447 listener.commandComcReceived(packetNo, time);
00448 }
00449 }
00450
00451 protected void fireDelinvReceived(final int tag) {
00452 model.getItemsManager().delinvReceived(tag);
00453 for (final CrossfireUpdateItemListener crossfireUpdateItemListener : crossfireUpdateItemListeners.getListeners()) {
00454 crossfireUpdateItemListener.delinvReceived(tag);
00455 }
00456 }
00457
00458 protected void fireDelitemReceived(@NotNull final int[] tags) {
00459 model.getItemsManager().delitemReceived(tags);
00460 for (final CrossfireUpdateItemListener crossfireUpdateItemListener : crossfireUpdateItemListeners.getListeners()) {
00461 crossfireUpdateItemListener.delitemReceived(tags);
00462 }
00463 }
00464
00465 protected void fireFaceReceived(final int faceNum, final int faceSetNum, final int faceChecksum, @NotNull final String faceName) {
00466 model.getFaceCache().addFace(faceNum, faceSetNum, faceChecksum, faceName);
00467 for (final CrossfireFaceListener crossfireFaceListener : crossfireFaceListeners.getListeners()) {
00468 crossfireFaceListener.faceReceived(faceNum, faceSetNum, faceChecksum, faceName);
00469 }
00470 }
00471
00472 protected void fireFailure(@NotNull final String command, @NotNull final String arguments) {
00473 for (final CrossfireFailureListener crossfireFailureListener : crossfireFailureListeners.getListeners()) {
00474 crossfireFailureListener.failure(command, arguments);
00475 }
00476 }
00477
00482 protected void clearFailure() {
00483 for (final CrossfireFailureListener crossfireFailureListener : crossfireFailureListeners.getListeners()) {
00484 crossfireFailureListener.clearFailure();
00485 }
00486 }
00487
00488 protected void fireAddItemReceived(final int location, final int tag, final int flags, final int weight, final int faceNum, final String name, final String namePl, final int anim, final int animSpeed, final int nrof, final int type) {
00489 model.getItemsManager().addItemReceived(location, tag, flags, weight, faceNum, name, namePl, anim, animSpeed, nrof, type);
00490 for (final CrossfireUpdateItemListener crossfireUpdateItemListener : crossfireUpdateItemListeners.getListeners()) {
00491 crossfireUpdateItemListener.addItemReceived(location, tag, flags, weight, faceNum, name, namePl, anim, animSpeed, nrof, type);
00492 }
00493 }
00494
00495 protected void fireMagicMap(final int x, final int y, @NotNull final byte[][] data) {
00496 if (crossfireUpdateMapListener != null) {
00497 synchronized (crossfireUpdateMapListener.mapBegin()) {
00498 assert crossfireUpdateMapListener != null;
00499 crossfireUpdateMapListener.magicMap(x, y, data);
00500 assert crossfireUpdateMapListener != null;
00501 crossfireUpdateMapListener.mapEnd();
00502 }
00503 }
00504 for (final CrossfireMagicmapListener listener : magicmapListeners.getListeners()) {
00505 listener.commandMagicmapReceived();
00506 }
00507 }
00508
00509 protected void fireMusicReceived(@NotNull final String music) {
00510 for (final CrossfireMusicListener listener : crossfireMusicListeners.getListeners()) {
00511 listener.commandMusicReceived(music);
00512 }
00513 }
00514
00515 protected void firePickupChanged(final int pickupOptions) {
00516 for (final CrossfirePickupListener crossfirePickupListener : crossfirePickupListeners.getListeners()) {
00517 crossfirePickupListener.pickupChanged(pickupOptions);
00518 }
00519 }
00520
00521 protected void firePlayerReceived(final int tag, final int weight, final int faceNum, @NotNull final String name) {
00522 model.getItemsManager().playerReceived(tag, weight, faceNum, name);
00523 for (final CrossfireUpdateItemListener crossfireUpdateItemListener : crossfireUpdateItemListeners.getListeners()) {
00524 crossfireUpdateItemListener.playerReceived(tag, weight, faceNum, name);
00525 }
00526 }
00527
00528 protected void fireCommandQueryReceived(@NotNull final String prompt, final int queryType) {
00529 for (final CrossfireQueryListener listener : queryListeners.getListeners()) {
00530 listener.commandQueryReceived(prompt, queryType);
00531 }
00532 }
00533
00534 protected void fireCommandSoundReceived(final int x, final int y, final int num, final int type) {
00535 for (final CrossfireSoundListener listener : crossfireSoundListeners.getListeners()) {
00536 listener.commandSoundReceived(x, y, num, type);
00537 }
00538 }
00539
00540 protected void fireCommandSound2Received(final int x, final int y, final int dir, final int volume, final int type, @NotNull final String action, @NotNull final String name) {
00541 for (final CrossfireSoundListener listener : crossfireSoundListeners.getListeners()) {
00542 listener.commandSound2Received(x, y, dir, volume, type, action, name);
00543 }
00544 }
00545
00546 protected void fireTick(final int tickNo) {
00547 for (final CrossfireTickListener listener : crossfireTickListeners.getListeners()) {
00548 listener.tick(tickNo);
00549 }
00550 }
00551
00552 protected void fireUpditemReceived(final int flags, final int tag, final int valLocation, final int valFlags, final int valWeight, final int valFaceNum, @NotNull final String valName, @NotNull final String valNamePl, final int valAnim, final int valAnimSpeed, final int valNrof) {
00553 model.getItemsManager().upditemReceived(flags, tag, valLocation, valFlags, valWeight, valFaceNum, valName, valNamePl, valAnim, valAnimSpeed, valNrof);
00554 for (final CrossfireUpdateItemListener crossfireUpdateItemListener : crossfireUpdateItemListeners.getListeners()) {
00555 crossfireUpdateItemListener.upditemReceived(flags, tag, valLocation, valFlags, valWeight, valFaceNum, valName, valNamePl, valAnim, valAnimSpeed, valNrof);
00556 }
00557 }
00558
00562 @Override
00563 public void drawInfo(@NotNull final String message, final int color) {
00564 for (final CrossfireDrawinfoListener listener : drawinfoListeners.getListeners()) {
00565 listener.commandDrawinfoReceived(message, color);
00566 }
00567 }
00568
00572 @Override
00573 public void drawextinfo(final int color, final int type, final int subtype, final String message) {
00574 for (final CrossfireDrawextinfoListener listener : drawextinfoListeners.getListeners()) {
00575 listener.commandDrawextinfoReceived(color, type, subtype, message);
00576 }
00577 }
00578
00582 @Override
00583 public void drawInfoSetDebugMode(final boolean printMessageTypes) {
00584 for (final CrossfireDrawextinfoListener listener : drawextinfoListeners.getListeners()) {
00585 listener.setDebugMode(printMessageTypes);
00586 }
00587 }
00588
00589 protected void fireReplySent() {
00590 for (final SentReplyListener sentReplyListener : sentReplyListeners.getListeners()) {
00591 sentReplyListener.replySent();
00592 }
00593 }
00594
00600 protected void notifyPacketWatcherListenersEmpty(@NotNull final String command) {
00601 for (final ReceivedPacketListener receivedPacketListener : receivedPacketListeners.getListeners()) {
00602 receivedPacketListener.processEmpty(command);
00603 }
00604 }
00605
00613 protected void notifyPacketWatcherListenersAscii(@NotNull final ByteBuffer packet, final int args) {
00614 final ReceivedPacketListener[] listeners = receivedPacketListeners.getListeners();
00615 if (listeners.length > 0) {
00616 final String command = extractCommand(packet);
00617 if (packet.hasRemaining()) {
00618 for (final ReceivedPacketListener receivedPacketListener : listeners) {
00619 packet.position(args);
00620 receivedPacketListener.processAscii(command, packet);
00621 }
00622 } else {
00623 notifyPacketWatcherListenersEmpty(command);
00624 }
00625 }
00626 }
00627
00635 protected void notifyPacketWatcherListenersShortArray(@NotNull final ByteBuffer packet, final int args) {
00636 final ReceivedPacketListener[] listeners = receivedPacketListeners.getListeners();
00637 if (listeners.length > 0) {
00638 final String command = extractCommand(packet);
00639 if (packet.hasRemaining()) {
00640 for (final ReceivedPacketListener receivedPacketListener : listeners) {
00641 packet.position(args);
00642 receivedPacketListener.processShortArray(command, packet);
00643 }
00644 } else {
00645 notifyPacketWatcherListenersEmpty(command);
00646 }
00647 }
00648 }
00649
00657 protected void notifyPacketWatcherListenersIntArray(@NotNull final ByteBuffer packet, final int args) {
00658 final ReceivedPacketListener[] listeners = receivedPacketListeners.getListeners();
00659 if (listeners.length > 0) {
00660 final String command = extractCommand(packet);
00661 if (packet.hasRemaining()) {
00662 for (final ReceivedPacketListener receivedPacketListener : listeners) {
00663 packet.position(args);
00664 receivedPacketListener.processIntArray(command, packet);
00665 }
00666 } else {
00667 notifyPacketWatcherListenersEmpty(command);
00668 }
00669 }
00670 }
00671
00679 protected void notifyPacketWatcherListenersShortInt(@NotNull final ByteBuffer packet, final int args) {
00680 final ReceivedPacketListener[] listeners = receivedPacketListeners.getListeners();
00681 if (listeners.length > 0) {
00682 final String command = extractCommand(packet);
00683 if (packet.hasRemaining()) {
00684 for (final ReceivedPacketListener receivedPacketListener : listeners) {
00685 packet.position(args);
00686 receivedPacketListener.processShortInt(command, packet);
00687 }
00688 } else {
00689 notifyPacketWatcherListenersEmpty(command);
00690 }
00691 }
00692 }
00693
00701 protected void notifyPacketWatcherListenersMixed(@NotNull final ByteBuffer packet, final int args) {
00702 final ReceivedPacketListener[] listeners = receivedPacketListeners.getListeners();
00703 if (listeners.length > 0) {
00704 final String command = extractCommand(packet);
00705 if (packet.hasRemaining()) {
00706 for (final ReceivedPacketListener receivedPacketListener : listeners) {
00707 packet.position(args);
00708 receivedPacketListener.processMixed(command, packet);
00709 }
00710 } else {
00711 notifyPacketWatcherListenersEmpty(command);
00712 }
00713 }
00714 }
00715
00723 protected void notifyPacketWatcherListenersStats(final int stat, @NotNull final Object... args) {
00724 final ReceivedPacketListener[] listeners = receivedPacketListeners.getListeners();
00725 if (listeners.length > 0) {
00726 for (final ReceivedPacketListener receivedPacketListener : listeners) {
00727 receivedPacketListener.processStats("stats", stat, args);
00728 }
00729 }
00730 }
00731
00739 protected void notifyPacketWatcherListenersNoData(@NotNull final ByteBuffer packet, final int args) {
00740 final ReceivedPacketListener[] listeners = receivedPacketListeners.getListeners();
00741 if (listeners.length > 0) {
00742 final String command = extractCommand(packet);
00743 if (packet.hasRemaining()) {
00744 for (final ReceivedPacketListener receivedPacketListener : listeners) {
00745 packet.position(args);
00746 receivedPacketListener.processNoData(command, packet);
00747 }
00748 } else {
00749 notifyPacketWatcherListenersEmpty(command);
00750 }
00751 }
00752 }
00753
00759 protected static String extractCommand(@NotNull final ByteBuffer packet) {
00760 int cmdLen;
00761 for (cmdLen = 0; cmdLen < packet.limit(); cmdLen++) {
00762 final byte ch = packet.get(cmdLen);
00763 if ((ch&0xFF) <= 0x20 || (ch&0xFF) >= 0x80) {
00764 break;
00765 }
00766 }
00767 return newString(packet, 0, cmdLen);
00768 }
00769
00777 protected static String newString(final ByteBuffer byteBuffer, final int start, final int len) {
00778 final byte[] tmp = new byte[len];
00779 for (int i = 0; i < len; i++) {
00780 tmp[i] = byteBuffer.get(start+i);
00781 }
00782 return new String(tmp, UTF8);
00783 }
00784
00785 protected void fireSelectCharacter(@NotNull final String accountName, @NotNull final String characterName) {
00786 model.getSpellsManager().selectCharacter();
00787 model.getQuestsManager().selectCharacter();
00788 for (final CrossfireAccountListener crossfireAccountListener : crossfireAccountListeners.getListeners()) {
00789 crossfireAccountListener.selectCharacter(accountName, characterName);
00790 }
00791 }
00792
00793 }