From 124fc5f25ef954db184f009143c260b0a0f182dc Mon Sep 17 00:00:00 2001 From: Bill Date: Tue, 16 Mar 2021 22:02:09 -0400 Subject: [PATCH] First commit --- .browserslistrc | 18 + .editorconfig | 16 + .eslintrc.json | 132 + .gitignore | 51 + .gitlab-ci.yml | 30 + .vscode/settings.json | 16 + LICENSE | 674 +++ index.ts | 1 + package-lock.json | 1747 ++++++++ package.json | 23 + src/core/INitroCore.ts | 11 + src/core/NitroCore.ts | 60 + src/core/asset/AssetManager.ts | 319 ++ src/core/asset/IAssetManager.ts | 19 + src/core/asset/NitroBundle.ts | 71 + src/core/asset/index.ts | 4 + src/core/asset/interfaces/IAsset.ts | 9 + src/core/asset/interfaces/IAssetAlias.ts | 6 + src/core/asset/interfaces/IAssetData.ts | 26 + src/core/asset/interfaces/IAssetDimension.ts | 6 + src/core/asset/interfaces/IAssetPalette.ts | 8 + .../interfaces/animation/IAssetAnimation.ts | 23 + .../animation/IAssetAnimationAdd.ts | 8 + .../animation/IAssetAnimationAvatar.ts | 6 + .../animation/IAssetAnimationDirection.ts | 4 + .../animation/IAssetAnimationFrame.ts | 8 + .../animation/IAssetAnimationFramePart.ts | 14 + .../animation/IAssetAnimationFramePartItem.ts | 5 + .../animation/IAssetAnimationOverride.ts | 8 + .../animation/IAssetAnimationRemove.ts | 4 + .../animation/IAssetAnimationShadow.ts | 4 + .../animation/IAssetAnimationSprite.ts | 11 + .../IAssetAnimationSpriteDirection.ts | 7 + src/core/asset/interfaces/animation/index.ts | 12 + src/core/asset/interfaces/index.ts | 8 + .../spritesheet/ISpritesheetData.ts | 8 + .../spritesheet/ISpritesheetFrame.ts | 25 + .../spritesheet/ISpritesheetMeta.ts | 12 + .../asset/interfaces/spritesheet/index.ts | 3 + .../visualization/IAssetVisualizationData.ts | 19 + .../IAssetVisualizationDirection.ts | 6 + .../visualization/IAssetVisualizationLayer.ts | 10 + .../animation/IAssetVisualAnimation.ts | 10 + .../animation/IAssetVisualAnimationLayer.ts | 9 + .../IAssetVisualAnimationSequence.ts | 8 + .../IAssetVisualAnimationSequenceFrame.ts | 11 + ...AssetVisualAnimationSequenceFrameOffset.ts | 6 + .../visualization/animation/index.ts | 5 + .../visualization/color/IAssetColor.ts | 6 + .../visualization/color/IAssetColorLayer.ts | 4 + .../interfaces/visualization/color/index.ts | 2 + .../visualization/gestures/IAssetGesture.ts | 5 + .../visualization/gestures/index.ts | 1 + .../asset/interfaces/visualization/index.ts | 7 + .../visualization/postures/IAssetPosture.ts | 5 + .../visualization/postures/index.ts | 1 + src/core/common/INitroManager.ts | 12 + src/core/common/IUpdateReceiver.ts | 6 + src/core/common/NitroManager.ts | 78 + src/core/common/disposable/Disposable.ts | 40 + src/core/common/disposable/IDisposable.ts | 5 + src/core/common/disposable/index.ts | 2 + src/core/common/index.ts | 5 + src/core/common/logger/INitroLogger.ts | 8 + src/core/common/logger/NitroLogger.ts | 89 + src/core/common/logger/index.ts | 2 + .../communication/CommunicationManager.ts | 53 + .../communication/ICommunicationManager.ts | 8 + src/core/communication/codec/BinaryReader.ts | 62 + src/core/communication/codec/BinaryWriter.ts | 94 + src/core/communication/codec/Byte.ts | 14 + src/core/communication/codec/ICodec.ts | 9 + src/core/communication/codec/Short.ts | 14 + .../codec/evawire/EvaWireDataWrapper.ts | 65 + .../codec/evawire/EvaWireFormat.ts | 87 + src/core/communication/codec/evawire/index.ts | 2 + src/core/communication/codec/index.ts | 6 + .../communication/connections/IConnection.ts | 19 + .../connections/IConnectionStateListener.ts | 4 + .../connections/SocketConnection.ts | 368 ++ .../enums/ClientDeviceCategoryEnum.ts | 5 + .../connections/enums/ClientPlatformEnum.ts | 7 + .../connections/enums/WebSocketEventEnum.ts | 7 + .../communication/connections/enums/index.ts | 3 + src/core/communication/connections/index.ts | 4 + .../events/SocketConnectionEvent.ts | 31 + src/core/communication/events/index.ts | 1 + src/core/communication/index.ts | 6 + .../messages/IMessageComposer.ts | 5 + .../messages/IMessageConfiguration.ts | 5 + .../messages/IMessageDataWrapper.ts | 13 + .../communication/messages/IMessageEvent.ts | 11 + .../communication/messages/IMessageParser.ts | 7 + .../messages/MessageClassManager.ts | 145 + .../communication/messages/MessageEvent.ts | 57 + src/core/communication/messages/index.ts | 7 + src/core/configuration/ConfigurationEvent.ts | 12 + .../configuration/ConfigurationManager.ts | 137 + .../configuration/IConfigurationManager.ts | 8 + src/core/configuration/index.ts | 3 + src/core/events/EventDispatcher.ts | 112 + src/core/events/IEventDispatcher.ts | 9 + src/core/events/ILinkEventTracker.ts | 5 + src/core/events/IWorkerEventTracker.ts | 4 + src/core/events/NitroEvent.ts | 4 + src/core/events/index.ts | 5 + src/core/index.ts | 8 + src/core/utils/AdvancedMap.ts | 157 + src/core/utils/NitroTimer.ts | 43 + src/core/utils/index.ts | 2 + src/index.ts | 1 + src/nitro/INitro.ts | 45 + src/nitro/Nitro.ts | 417 ++ .../avatar/AvatarAssetDownloadLibrary.ts | 74 + .../avatar/AvatarAssetDownloadManager.ts | 343 ++ src/nitro/avatar/AvatarFigureContainer.ts | 116 + src/nitro/avatar/AvatarImage.ts | 1055 +++++ .../avatar/AvatarImageBodyPartContainer.ts | 88 + src/nitro/avatar/AvatarImagePartContainer.ts | 137 + src/nitro/avatar/AvatarRenderManager.ts | 477 +++ src/nitro/avatar/AvatarStructure.ts | 653 +++ .../avatar/EffectAssetDownloadLibrary.ts | 86 + .../avatar/EffectAssetDownloadManager.ts | 302 ++ src/nitro/avatar/IAvatarEffectListener.ts | 6 + src/nitro/avatar/IAvatarFigureContainer.ts | 10 + src/nitro/avatar/IAvatarImage.ts | 37 + src/nitro/avatar/IAvatarImageListener.ts | 6 + src/nitro/avatar/IAvatarRenderManager.ts | 28 + src/nitro/avatar/IOutfit.ts | 5 + src/nitro/avatar/PlaceHolderAvatarImage.ts | 18 + src/nitro/avatar/actions/ActionDefinition.ts | 224 + src/nitro/avatar/actions/ActionType.ts | 44 + src/nitro/avatar/actions/ActiveActionData.ts | 74 + .../avatar/actions/AvatarActionManager.ts | 187 + src/nitro/avatar/actions/IActionDefinition.ts | 20 + src/nitro/avatar/actions/IActiveActionData.ts | 11 + src/nitro/avatar/alias/AssetAlias.ts | 37 + .../avatar/alias/AssetAliasCollection.ts | 90 + .../avatar/animation/AddDataContainer.ts | 61 + src/nitro/avatar/animation/Animation.ts | 312 ++ .../avatar/animation/AnimationLayerData.ts | 112 + .../avatar/animation/AnimationManager.ts | 50 + .../avatar/animation/AvatarDataContainer.ts | 137 + .../animation/DirectionDataContainer.ts | 16 + src/nitro/avatar/animation/IAnimation.ts | 11 + .../avatar/animation/IAnimationLayerData.ts | 12 + .../avatar/animation/IAnimationManager.ts | 9 + .../avatar/animation/IAvatarDataContainer.ts | 12 + .../avatar/animation/ISpriteDataContainer.ts | 14 + .../avatar/animation/SpriteDataContainer.ts | 96 + .../avatar/cache/AvatarImageActionCache.ts | 96 + .../avatar/cache/AvatarImageBodyPartCache.ts | 57 + src/nitro/avatar/cache/AvatarImageCache.ts | 527 +++ .../avatar/cache/AvatarImageDirectionCache.ts | 59 + src/nitro/avatar/cache/ImageData.ts | 65 + .../avatar/data/HabboAvatarAnimations.json | 827 ++++ .../avatar/data/HabboAvatarGeometry.json | 1830 +++++++++ .../avatar/data/HabboAvatarPartSets.json | 418 ++ src/nitro/avatar/enum/AvatarAction.ts | 127 + src/nitro/avatar/enum/AvatarDirectionAngle.ts | 7 + .../avatar/enum/AvatarEditorFigureCategory.ts | 10 + .../avatar/enum/AvatarEditorInstanceId.ts | 7 + .../avatar/enum/AvatarEditorSideCategory.ts | 5 + src/nitro/avatar/enum/AvatarFigurePartType.ts | 29 + src/nitro/avatar/enum/AvatarGuideStatus.ts | 6 + src/nitro/avatar/enum/AvatarScaleType.ts | 5 + src/nitro/avatar/enum/AvatarSetType.ts | 6 + src/nitro/avatar/enum/GeometryType.ts | 8 + src/nitro/avatar/enum/RenderMode.ts | 7 + .../events/AvatarRenderEffectLibraryEvent.ts | 21 + src/nitro/avatar/events/AvatarRenderEvent.ts | 4 + .../avatar/events/AvatarRenderLibraryEvent.ts | 21 + src/nitro/avatar/figuredata/FigureData.ts | 311 ++ src/nitro/avatar/figuredata/FigureDataView.ts | 43 + .../avatar/geometry/AvatarModelGeometry.ts | 287 ++ src/nitro/avatar/geometry/AvatarSet.ts | 92 + src/nitro/avatar/geometry/GeometryBodyPart.ts | 194 + src/nitro/avatar/geometry/GeometryItem.ts | 55 + src/nitro/avatar/geometry/Matrix4x4.ts | 133 + src/nitro/avatar/geometry/Node3D.ts | 33 + src/nitro/avatar/geometry/Vector3D.ts | 113 + src/nitro/avatar/pets/PetCustomPart.ts | 43 + src/nitro/avatar/pets/PetFigureData.ts | 228 ++ src/nitro/avatar/pets/PetType.ts | 38 + src/nitro/avatar/structure/AnimationData.ts | 58 + src/nitro/avatar/structure/AvatarCanvas.ts | 47 + .../structure/AvatarStructureDownload.ts | 57 + src/nitro/avatar/structure/FigureSetData.ts | 152 + src/nitro/avatar/structure/IFigureSetData.ts | 5 + src/nitro/avatar/structure/IStructureData.ts | 12 + src/nitro/avatar/structure/PartSetsData.ts | 120 + .../structure/animation/AnimationAction.ts | 138 + .../animation/AnimationActionPart.ts | 30 + .../structure/animation/AnimationFrame.ts | 21 + .../avatar/structure/figure/FigurePart.ts | 66 + .../avatar/structure/figure/FigurePartSet.ts | 144 + .../avatar/structure/figure/IFigurePart.ts | 9 + .../avatar/structure/figure/IFigurePartSet.ts | 16 + src/nitro/avatar/structure/figure/IPalette.ts | 8 + .../avatar/structure/figure/IPartColor.ts | 8 + src/nitro/avatar/structure/figure/ISetType.ts | 12 + src/nitro/avatar/structure/figure/Palette.ts | 46 + .../avatar/structure/figure/PartColor.ts | 46 + src/nitro/avatar/structure/figure/SetType.ts | 105 + .../avatar/structure/parts/ActivePartSet.ts | 26 + .../avatar/structure/parts/PartDefinition.ts | 64 + .../INitroCommunicationManager.ts | 12 + .../NitroCommunicationManager.ts | 124 + src/nitro/communication/NitroMessages.ts | 971 +++++ .../demo/NitroCommunicationDemo.ts | 205 + .../demo/NitroCommunicationDemoEvent.ts | 27 + .../messages/incoming/IncomingHeader.ts | 241 ++ .../AvailabilityStatusMessageEvent.ts | 16 + .../incoming/avatar/ChangeNameUpdateEvent.ts | 25 + .../incoming/catalog/CatalogClubEvent.ts | 16 + .../incoming/catalog/CatalogClubGiftsEvent.ts | 16 + .../catalog/CatalogGiftConfigurationEvent.ts | 17 + .../CatalogGiftUsernameUnavailableEvent.ts | 16 + .../incoming/catalog/CatalogGroupsEvent.ts | 16 + .../incoming/catalog/CatalogModeEvent.ts | 16 + .../incoming/catalog/CatalogPageEvent.ts | 16 + .../incoming/catalog/CatalogPagesEvent.ts | 16 + .../incoming/catalog/CatalogPurchaseEvent.ts | 16 + .../catalog/CatalogPurchaseFailedEvent.ts | 16 + .../CatalogPurchaseUnavailableEvent.ts | 16 + .../catalog/CatalogRedeemVoucherErrorEvent.ts | 16 + .../catalog/CatalogRedeemVoucherOkEvent.ts | 16 + .../incoming/catalog/CatalogSearchEvent.ts | 16 + .../incoming/catalog/CatalogSoldOutEvent.ts | 16 + .../incoming/catalog/CatalogUpdatedEvent.ts | 16 + .../incoming/client/ClientPingEvent.ts | 16 + .../incoming/desktop/DesktopViewEvent.ts | 16 + .../friendlist/AcceptFriendFailureData.ts | 25 + .../friendlist/AcceptFriendResultEvent.ts | 16 + .../FindFriendsProcessResultEvent.ts | 16 + .../friendlist/FollowFriendFailedEvent.ts | 17 + .../incoming/friendlist/FriendCategoryData.ts | 25 + .../friendlist/FriendListFragmentEvent.ts | 16 + .../friendlist/FriendListUpdateEvent.ts | 16 + .../friendlist/FriendNotificationEvent.ts | 17 + .../incoming/friendlist/FriendParser.ts | 109 + .../incoming/friendlist/FriendRequestData.ts | 39 + .../friendlist/FriendRequestsEvent.ts | 16 + .../friendlist/HabboSearchResultData.ts | 74 + .../friendlist/HabboSearchResultEvent.ts | 16 + .../friendlist/InstantMessageErrorEvent.ts | 16 + .../incoming/friendlist/MessageErrorEvent.ts | 16 + .../incoming/friendlist/MessengerInitEvent.ts | 16 + .../friendlist/MiniMailNewMessageEvent.ts | 16 + .../friendlist/MiniMailUnreadCountEvent.ts | 16 + .../friendlist/NewConsoleMessageEvent.ts | 16 + .../friendlist/NewFriendRequestEvent.ts | 16 + .../friendlist/RoomInviteErrorEvent.ts | 16 + .../incoming/friendlist/RoomInviteEvent.ts | 16 + .../incoming/game/LoadGameUrlEvent.ts | 16 + .../incoming/generic/GenericErrorEvent.ts | 16 + .../incoming/group/GroupBadgePartsEvent.ts | 16 + .../incoming/group/GroupBuyDataEvent.ts | 16 + .../group/GroupConfirmMemberRemoveEvent.ts | 16 + .../incoming/group/GroupInformationEvent.ts | 16 + .../incoming/group/GroupMembersEvent.ts | 16 + .../incoming/group/GroupSettingsEvent.ts | 16 + .../help/CallForHelpResultMessageEvent.ts | 16 + .../inventory/achievements/Achievement.ts | 156 + .../achievements/AchievementEvent.ts | 16 + .../achievements/AchievementResolution.ts | 59 + .../achievements/AchievementsEvent.ts | 16 + .../achievements/AchievementsScoreEvent.ts | 16 + .../inventory/avatareffect/AvatarEffect.ts | 69 + .../AvatarEffectActivatedEvent.ts | 16 + .../avatareffect/AvatarEffectAddedEvent.ts | 16 + .../avatareffect/AvatarEffectExpiredEvent.ts | 16 + .../avatareffect/AvatarEffectSelectedEvent.ts | 16 + .../avatareffect/AvatarEffectsEvent.ts | 16 + .../incoming/inventory/badges/BadgesEvent.ts | 16 + .../incoming/inventory/badges/_Str_8120.ts | 16 + .../incoming/inventory/badges/_Str_8179.ts | 16 + .../incoming/inventory/badges/_Str_8980.ts | 16 + .../bots/BotAddedToInventoryEvent.ts | 16 + .../inventory/bots/BotInventoryEvent.ts | 16 + .../bots/BotInventoryMessageEvent.ts | 16 + .../bots/BotRemovedFromInventoryEvent.ts | 16 + .../clothes/FigureSetIdsMessageEvent.ts | 16 + .../incoming/inventory/clothes/_Str_16135.ts | 16 + .../incoming/inventory/clothes/_Str_17532.ts | 16 + .../furni/FurnitureListAddOrUpdateEvent.ts | 16 + .../inventory/furni/FurnitureListEvent.ts | 16 + .../furni/FurnitureListInvalidateEvent.ts | 16 + .../furni/FurnitureListRemovedEvent.ts | 16 + .../furni/FurniturePostItPlacedEvent.ts | 16 + .../inventory/furni/IFurnitureItemData.ts | 28 + .../furni/gifts/FurnitureGiftOpenedEvent.ts | 17 + .../pets/PetAddedToInventoryEvent.ts | 16 + .../inventory/pets/PetInventoryEvent.ts | 16 + .../pets/PetRemovedFromInventoryEvent.ts | 16 + .../inventory/trading/TradingAcceptEvent.ts | 26 + .../inventory/trading/TradingCloseEvent.ts | 21 + .../trading/TradingCompletedEvent.ts | 16 + .../trading/TradingConfirmationEvent.ts | 16 + .../inventory/trading/TradingListItem.ts | 163 + .../inventory/trading/TradingListItemEvent.ts | 57 + .../inventory/trading/TradingNotOpenEvent.ts | 16 + .../inventory/trading/TradingOpenEvent.ts | 36 + .../trading/TradingOpenFailedEvent.ts | 16 + .../trading/TradingOtherNotAllowedEvent.ts | 16 + .../trading/TradingYouAreNotAllowedEvent.ts | 16 + .../moderation/ModeratorMessageEvent.ts | 16 + .../modtool/ModtoolCallForHelpTopicsEvent.ts | 16 + .../incoming/modtool/ModtoolMainEvent.ts | 17 + .../modtool/ModtoolReceivedRoomsUserEvent.ts | 16 + .../modtool/ModtoolRoomChatlogEvent.ts | 16 + .../incoming/modtool/ModtoolRoomInfoEvent.ts | 16 + .../modtool/ModtoolUserChatlogEvent.ts | 16 + .../incoming/modtool/ModtoolUserInfoEvent.ts | 16 + .../navigator/NavigatorCategoriesEvent.ts | 16 + .../navigator/NavigatorCollapsedEvent.ts | 16 + .../NavigatorEventCategoriesEvent.ts | 16 + .../navigator/NavigatorHomeRoomEvent.ts | 16 + .../navigator/NavigatorLiftedEvent.ts | 16 + .../navigator/NavigatorMetadataEvent.ts | 16 + .../NavigatorOpenRoomCreatorEvent.ts | 16 + .../navigator/NavigatorSearchEvent.ts | 16 + .../navigator/NavigatorSearchesEvent.ts | 16 + .../navigator/NavigatorSettingsEvent.ts | 16 + .../incoming/notifications/BotErrorEvent.ts | 16 + .../HabboBroadcastMessageEvent.ts | 16 + .../notifications/HotelWillShutdownEvent.ts | 16 + .../notifications/MOTDNotificationEvent.ts | 16 + .../NotificationDialogMessageEvent.ts | 16 + .../notifications/PetPlacingErrorEvent.ts | 16 + .../notifications/RespectReceivedEvent.ts | 16 + .../notifications/UnseenItemsEvent.ts | 16 + .../room/access/RoomEnterErrorEvent.ts | 16 + .../incoming/room/access/RoomEnterEvent.ts | 16 + .../incoming/room/access/RoomForwardEvent.ts | 16 + .../doorbell/RoomDoorbellAcceptedEvent.ts | 16 + .../room/access/doorbell/RoomDoorbellEvent.ts | 21 + .../doorbell/RoomDoorbellRejectedEvent.ts | 16 + .../access/rights/RoomRightsClearEvent.ts | 16 + .../room/access/rights/RoomRightsEvent.ts | 16 + .../access/rights/RoomRightsOwnerEvent.ts | 16 + .../room/bots/BotCommandConfigurationEvent.ts | 16 + .../room/data/RoomBannedUsersEvent.ts | 16 + .../room/data/RoomChatSettingsEvent.ts | 16 + .../incoming/room/data/RoomInfoEvent.ts | 16 + .../incoming/room/data/RoomInfoOwnerEvent.ts | 16 + .../incoming/room/data/RoomScoreEvent.ts | 16 + .../room/data/RoomSettingsErrorEvent.ts | 16 + .../incoming/room/data/RoomSettingsEvent.ts | 16 + .../room/data/RoomSettingsSavedEvent.ts | 16 + .../room/data/RoomSettingsUpdatedEvent.ts | 16 + .../room/data/RoomUsersWithRightsEvent.ts | 16 + .../room/engine/ObjectsRollingEvent.ts | 16 + .../incoming/room/engine/RoomCreatedEvent.ts | 16 + .../room/furniture/FurnitureAliasesEvent.ts | 16 + .../room/furniture/FurnitureDataEvent.ts | 16 + .../room/furniture/FurnitureItemDataEvent.ts | 16 + .../furniture/FurnitureStackHeightEvent.ts | 16 + .../room/furniture/FurnitureState2Event.ts | 16 + .../room/furniture/FurnitureStateEvent.ts | 16 + .../furniture/LoveLockFurniFinishedEvent.ts | 16 + .../LoveLockFurniFriendConfirmedEvent.ts | 16 + .../room/furniture/LoveLockFurniStartEvent.ts | 16 + .../RoomDimmerPresetsMessageEvent.ts | 16 + .../furniture/floor/FurnitureFloorAddEvent.ts | 16 + .../furniture/floor/FurnitureFloorEvent.ts | 16 + .../floor/FurnitureFloorRemoveEvent.ts | 16 + .../floor/FurnitureFloorUpdateEvent.ts | 16 + .../room/furniture/moodlightFromServer.ts | 64 + .../furniture/wall/FurnitureWallAddEvent.ts | 16 + .../room/furniture/wall/FurnitureWallEvent.ts | 16 + .../wall/FurnitureWallRemoveEvent.ts | 16 + .../wall/FurnitureWallUpdateEvent.ts | 16 + .../incoming/room/mapping/RoomDoorEvent.ts | 16 + .../room/mapping/RoomHeightMapEvent.ts | 16 + .../room/mapping/RoomHeightMapUpdateEvent.ts | 16 + .../incoming/room/mapping/RoomModelEvent.ts | 16 + .../room/mapping/RoomModelNameEvent.ts | 16 + .../incoming/room/mapping/RoomPaintEvent.ts | 16 + .../room/mapping/RoomThicknessEvent.ts | 16 + .../incoming/room/pet/PetFigureUpdateEvent.ts | 16 + .../incoming/room/pet/PetInfoEvent.ts | 16 + .../messages/incoming/room/pet/_Str_3763.ts | 55 + .../messages/incoming/room/pet/_Str_5753.ts | 40 + .../room/session/YouArePlayingGameEvent.ts | 16 + .../incoming/room/unit/RoomUnitDanceEvent.ts | 16 + .../incoming/room/unit/RoomUnitEffectEvent.ts | 16 + .../incoming/room/unit/RoomUnitEvent.ts | 16 + .../room/unit/RoomUnitExpressionEvent.ts | 16 + .../room/unit/RoomUnitHandItemEvent.ts | 16 + .../unit/RoomUnitHandItemReceivedEvent.ts | 16 + .../incoming/room/unit/RoomUnitIdleEvent.ts | 16 + .../incoming/room/unit/RoomUnitInfoEvent.ts | 16 + .../incoming/room/unit/RoomUnitNumberEvent.ts | 16 + .../incoming/room/unit/RoomUnitRemoveEvent.ts | 16 + .../incoming/room/unit/RoomUnitStatusEvent.ts | 16 + .../room/unit/chat/FloodControlEvent.ts | 16 + .../room/unit/chat/RemainingMuteEvent.ts | 16 + .../room/unit/chat/RoomUnitChatEvent.ts | 16 + .../room/unit/chat/RoomUnitChatShoutEvent.ts | 16 + .../unit/chat/RoomUnitChatWhisperEvent.ts | 16 + .../room/unit/chat/RoomUnitTypingEvent.ts | 16 + .../incoming/roomevents/ActionDefinition.ts | 47 + .../roomevents/ConditionDefinition.ts | 24 + .../incoming/roomevents/RoomMutedEvent.ts | 16 + .../incoming/roomevents/TriggerDefinition.ts | 40 + .../incoming/roomevents/Triggerable.ts | 100 + .../roomevents/WiredFurniActionEvent.ts | 16 + .../roomevents/WiredFurniConditionEvent.ts | 16 + .../roomevents/WiredFurniTriggerEvent.ts | 16 + .../incoming/roomevents/WiredOpenEvent.ts | 16 + .../WiredRewardResultMessageEvent.ts | 19 + .../roomevents/WiredSaveSuccessEvent.ts | 16 + .../roomevents/WiredValidationErrorEvent.ts | 16 + .../incoming/security/AuthenticatedEvent.ts | 16 + .../incoming/user/IgnoreResultEvent.ts | 16 + .../incoming/user/IgnoredUsersEvent.ts | 16 + .../incoming/user/InClientLinkEvent.ts | 16 + .../incoming/user/access/UserPerksEvent.ts | 16 + .../user/access/UserPermissionsEvent.ts | 16 + .../user/data/UserCurrentBadgesEvent.ts | 16 + .../incoming/user/data/UserFigureEvent.ts | 16 + .../incoming/user/data/UserInfoEvent.ts | 16 + .../user/data/UserNameChangeMessageEvent.ts | 16 + .../incoming/user/data/UserProfileEvent.ts | 16 + .../user/data/UserRelationshipsEvent.ts | 16 + .../incoming/user/data/UserSettingsEvent.ts | 16 + .../inventory/currency/UserCreditsEvent.ts | 16 + .../inventory/currency/UserCurrencyEvent.ts | 16 + .../currency/UserCurrencyUpdateEvent.ts | 16 + .../subscription/UserSubscriptionEvent.ts | 16 + .../user/wardrobe/UserWardrobePageEvent.ts | 16 + .../messages/outgoing/OutgoingHeader.ts | 225 + .../RequestAchievementsMessageComposer.ts | 21 + .../outgoing/catalog/CatalogGroupsComposer.ts | 21 + .../outgoing/catalog/CatalogModeComposer.ts | 21 + .../outgoing/catalog/CatalogPageComposer.ts | 21 + .../catalog/CatalogPurchaseComposer.ts | 21 + .../catalog/CatalogPurchaseGiftComposer.ts | 21 + ...CatalogRequestGiftConfigurationComposer.ts | 21 + .../catalog/CatalogRequestVipGiftsComposer.ts | 21 + .../CatalogRequestVipOffersComposer.ts | 21 + .../outgoing/catalog/CatalogSearchComposer.ts | 21 + .../catalog/CatalogSelectClubGiftComposer.ts | 21 + .../catalog/RedeemItemClothingComposer.ts | 21 + .../outgoing/catalog/RedeemVoucherComposer.ts | 21 + .../outgoing/client/ClientPongComposer.ts | 21 + .../client/ClientReleaseVersionComposer.ts | 24 + .../outgoing/desktop/DesktopViewComposer.ts | 21 + .../friendlist/AcceptFriendComposer.ts | 21 + .../friendlist/DeclineFriendComposer.ts | 21 + .../friendlist/FindNewFriendsComposer.ts | 21 + .../friendlist/FollowFriendComposer.ts | 21 + .../friendlist/FriendListUpdateComposer.ts | 21 + .../friendlist/GetFriendRequestsComposer.ts | 21 + .../friendlist/HabboSearchComposer.ts | 21 + .../friendlist/MessengerInitComposer.ts | 21 + .../friendlist/RemoveFriendComposer.ts | 21 + .../friendlist/RequestFriendComposer.ts | 21 + .../friendlist/SendMessageComposer.ts | 21 + .../friendlist/SendRoomInviteComposer.ts | 21 + .../SetRelationshipStatusComposer.ts | 21 + .../outgoing/friendlist/VisitUserComposer.ts | 21 + .../outgoing/group/GroupAdminGiveComposer.ts | 21 + .../outgoing/group/GroupAdminTakeComposer.ts | 21 + .../outgoing/group/GroupBadgePartsComposer.ts | 21 + .../outgoing/group/GroupBuyComposer.ts | 21 + .../outgoing/group/GroupBuyDataComposer.ts | 21 + .../group/GroupConfirmRemoveMemberComposer.ts | 21 + .../outgoing/group/GroupDeleteComposer.ts | 21 + .../group/GroupInformationComposer.ts | 21 + .../outgoing/group/GroupJoinComposer.ts | 21 + .../outgoing/group/GroupMembersComposer.ts | 21 + .../group/GroupMembershipAcceptComposer.ts | 21 + .../group/GroupMembershipDeclineComposer.ts | 21 + .../group/GroupRemoveMemberComposer.ts | 21 + .../outgoing/group/GroupSaveBadgeComposer.ts | 21 + .../outgoing/group/GroupSaveColorsComposer.ts | 21 + .../group/GroupSaveInformationComposer.ts | 21 + .../group/GroupSavePreferencesComposer.ts | 21 + .../outgoing/group/GroupSettingsComposer.ts | 21 + .../InfoRetrieveBaseMessageComposer.ts | 21 + .../handshake/SecurityTicketComposer.ts | 21 + .../inventory/badges/RequestBadgesComposer.ts | 21 + .../badges/SetActivatedBadgesComposer.ts | 40 + .../inventory/bots/GetBotInventoryComposer.ts | 21 + .../inventory/furni/FurnitureList2Composer.ts | 21 + .../inventory/furni/FurnitureListComposer.ts | 21 + .../inventory/pets/RequestPetsComposer.ts | 21 + .../trading/TradingAcceptComposer.ts | 21 + .../trading/TradingCancelComposer.ts | 21 + .../inventory/trading/TradingCloseComposer.ts | 21 + .../trading/TradingConfirmationComposer.ts | 21 + .../trading/TradingListAddItemComposer.ts | 21 + .../trading/TradingListAddItemsComposer.ts | 21 + .../trading/TradingListRemoveItemComposer.ts | 21 + .../inventory/trading/TradingOpenComposer.ts | 21 + .../trading/TradingUnacceptComposer.ts | 21 + .../ModtoolChangeRoomSettingsComposer.ts | 21 + .../modtool/ModtoolEventAlertComposer.ts | 27 + .../ModtoolRequestRoomChatlogComposer.ts | 21 + .../modtool/ModtoolRequestRoomInfoComposer.ts | 21 + .../ModtoolRequestUserChatlogComposer.ts | 21 + .../modtool/ModtoolRequestUserInfoComposer.ts | 21 + .../ModtoolRequestUserRoomsComposer.ts | 21 + .../modtool/ModtoolRoomAlertComposer.ts | 23 + .../modtool/ModtoolSanctionAlertComposer.ts | 27 + .../modtool/ModtoolSanctionBanComposer.ts | 29 + .../modtool/ModtoolSanctionKickComposer.ts | 27 + .../modtool/ModtoolSanctionMuteComposer.ts | 27 + .../ModtoolSanctionTradelockComposer.ts | 28 + .../navigator/ConvertGlobalRoomIdComposer.ts | 21 + .../navigator/NavigatorCategoriesComposer.ts | 21 + .../NavigatorCategoryListModeComposer.ts | 21 + .../navigator/NavigatorInitComposer.ts | 21 + .../navigator/NavigatorSearchCloseComposer.ts | 21 + .../navigator/NavigatorSearchComposer.ts | 21 + .../navigator/NavigatorSearchOpenComposer.ts | 21 + .../navigator/NavigatorSearchSaveComposer.ts | 21 + .../navigator/NavigatorSettingsComposer.ts | 21 + .../NavigatorSettingsSaveComposer.ts | 21 + .../outgoing/pet/PetRespectComposer.ts | 21 + .../outgoing/pet/RequestPetInfoComposer.ts | 21 + .../outgoing/room/RoomCreateComposer.ts | 21 + .../room/access/RoomDoorbellAccessComposer.ts | 21 + .../outgoing/room/access/RoomEnterComposer.ts | 21 + .../action/RoomAmbassadorAlertComposer.ts | 21 + .../room/action/RoomBanUserComposer.ts | 21 + .../room/action/RoomDeleteComposer.ts | 21 + .../room/action/RoomGiveRightsComposer.ts | 21 + .../room/action/RoomKickUserComposer.ts | 21 + .../room/action/RoomLikeRoomComposer.ts | 21 + .../room/action/RoomMuteUserComposer.ts | 21 + .../room/action/RoomStaffPickComposer.ts | 21 + .../room/action/RoomTakeRightsComposer.ts | 21 + .../room/action/RoomUnbanUserComposer.ts | 21 + .../bots/RequestBotConfigurationComposer.ts | 21 + .../room/data/RoomBannedUsersComposer.ts | 21 + .../outgoing/room/data/RoomInfoComposer.ts | 21 + .../room/data/RoomSettingsComposer.ts | 21 + .../room/data/RoomUsersWithRightsComposer.ts | 21 + .../room/data/SaveRoomSettingsComposer.ts | 70 + .../outgoing/room/engine/BotPlaceComposer.ts | 21 + .../outgoing/room/engine/BotRemoveComposer.ts | 21 + .../room/engine/BotSkillSaveComposer.ts | 21 + .../room/engine/GetItemDataComposer.ts | 21 + .../room/engine/ModifyWallItemDataComposer.ts | 21 + .../outgoing/room/engine/PetMoveComposer.ts | 21 + .../outgoing/room/engine/PetPlaceComposer.ts | 21 + .../outgoing/room/engine/PetRemoveComposer.ts | 21 + .../room/engine/RemoveWallItemComposer.ts | 21 + .../furniture/FurnitureAliasesComposer.ts | 21 + .../room/furniture/FurniturePickupComposer.ts | 21 + .../room/furniture/FurniturePlaceComposer.ts | 40 + .../furniture/FurniturePlacePaintComposer.ts | 21 + .../furniture/FurniturePostItPlaceComposer.ts | 21 + .../furniture/ads/RoomAdsUpdateComposer.ts | 23 + .../dimmer/MoodlightSettingsComposer.ts | 21 + .../dimmer/MoodlightSettingsSaveComposer.ts | 21 + .../dimmer/MoodlightTogggleStateComposer.ts | 21 + .../floor/FurnitureFloorUpdateComposer.ts | 21 + .../logic/FurnitureColorWheelComposer.ts | 21 + .../logic/FurnitureDiceActivateComposer.ts | 21 + .../logic/FurnitureDiceDeactivateComposer.ts | 21 + .../logic/FurnitureExchangeComposer.ts | 21 + .../logic/FurnitureMultiStateComposer.ts | 21 + .../logic/FurnitureOneWayDoorComposer.ts | 21 + .../logic/FurnitureRandomStateComposer.ts | 21 + .../logic/FurnitureStackHeightComposer.ts | 21 + .../logic/FurnitureWallMultiStateComposer.ts | 21 + .../logic/LoveLockStartConfirmComposer.ts | 21 + .../FurnitureMannequinSaveLookComposer.ts | 21 + .../FurnitureMannequinSaveNameComposer.ts | 21 + .../furniture/presents/OpenPresentComposer.ts | 21 + .../furniture/toner/ApplyTonerComposer.ts | 21 + .../wall/FurnitureWallUpdateComposer.ts | 21 + .../room/mapping/RoomModelComposer.ts | 21 + .../room/unit/RoomUnitActionComposer.ts | 21 + .../room/unit/RoomUnitDanceComposer.ts | 21 + .../room/unit/RoomUnitDropHandItemComposer.ts | 21 + .../room/unit/RoomUnitGiveHandItemComposer.ts | 21 + .../room/unit/RoomUnitLookComposer.ts | 21 + .../room/unit/RoomUnitPostureComposer.ts | 21 + .../room/unit/RoomUnitSignComposer.ts | 21 + .../room/unit/RoomUnitWalkComposer.ts | 21 + .../room/unit/chat/RoomUnitChatComposer.ts | 21 + .../unit/chat/RoomUnitChatShoutComposer.ts | 21 + .../unit/chat/RoomUnitChatStyleComposer.ts | 21 + .../unit/chat/RoomUnitChatWhisperComposer.ts | 21 + .../unit/chat/RoomUnitTypingStartComposer.ts | 21 + .../unit/chat/RoomUnitTypingStopComposer.ts | 21 + .../ApplySnapshotMessageComposer.ts | 21 + .../roomevents/OpenMessageComposer.ts | 21 + .../outgoing/roomevents/RoomMuteComposer.ts | 21 + .../roomevents/UpdateActionMessageComposer.ts | 21 + .../UpdateConditionMessageComposer.ts | 21 + .../UpdateTriggerMessageComposer.ts | 21 + .../outgoing/user/UserRespectComposer.ts | 21 + .../user/data/GetIgnoredUsersComposer.ts | 21 + .../outgoing/user/data/IgnoreUserComposer.ts | 21 + .../user/data/IgnoreUserIdComposer.ts | 21 + .../user/data/UnignoreUserComposer.ts | 21 + .../user/data/UserCurrentBadgesComposer.ts | 21 + .../outgoing/user/data/UserFigureComposer.ts | 21 + .../user/data/UserHomeRoomComposer.ts | 21 + .../outgoing/user/data/UserMottoComposer.ts | 21 + .../outgoing/user/data/UserProfileComposer.ts | 21 + .../user/data/UserRelationshipsComposer.ts | 21 + .../currency/UserCurrencyComposer.ts | 21 + .../subscription/UserSubscriptionComposer.ts | 21 + .../UserSettingsCameraFollowComposer.ts | 21 + .../settings/UserSettingsOldChatComposer.ts | 21 + .../UserSettingsRoomInvitesComposer.ts | 21 + .../settings/UserSettingsSoundComposer.ts | 21 + .../user/wardrobe/UserWardrobePageComposer.ts | 21 + .../user/wardrobe/UserWardrobeSaveComposer.ts | 21 + .../AvailabilityStatusMessageParser.ts | 48 + .../parser/avatar/ChangeNameUpdateParser.ts | 52 + .../parser/catalog/CatalogClubGiftsParser.ts | 84 + .../parser/catalog/CatalogClubParser.ts | 36 + .../catalog/CatalogGiftConfigurationParser.ts | 109 + .../CatalogGiftUsernameUnavailableParser.ts | 21 + .../parser/catalog/CatalogGroupsParser.ts | 36 + .../parser/catalog/CatalogModeParser.ts | 28 + .../parser/catalog/CatalogPageParser.ts | 108 + .../parser/catalog/CatalogPagesParser.ts | 43 + .../catalog/CatalogPurchaseFailedParser.ts | 28 + .../parser/catalog/CatalogPurchaseParser.ts | 29 + .../CatalogPurchaseUnavailableParser.ts | 28 + .../CatalogRedeemVoucherErrorParser.ts | 27 + .../catalog/CatalogRedeemVoucherOkParser.ts | 35 + .../parser/catalog/CatalogSearchParser.ts | 29 + .../parser/catalog/CatalogSoldOutParser.ts | 17 + .../parser/catalog/CatalogUpdatedParser.ts | 37 + .../catalog/utils/CatalogClubOfferData.ts | 134 + .../catalog/utils/CatalogFrontPageItem.ts | 109 + .../parser/catalog/utils/CatalogGroupData.ts | 91 + .../catalog/utils/CatalogLocalizationData.ts | 59 + .../parser/catalog/utils/CatalogPageData.ts | 100 + .../catalog/utils/CatalogPageOfferData.ts | 133 + .../catalog/utils/CatalogProductOfferData.ts | 98 + .../catalog/utils/CatalogPurchaseData.ts | 117 + .../parser/catalog/utils/CatalogSearchData.ts | 46 + .../catalog/utils/ICatalogLocalizationData.ts | 5 + .../parser/catalog/utils/ICatalogPageData.ts | 10 + .../catalog/utils/ICatalogPageParser.ts | 17 + .../parser/catalog/utils/_Str_5178.ts | 64 + .../parser/client/ClientPingParser.ts | 17 + .../parser/desktop/DesktopViewParser.ts | 17 + .../friendlist/AcceptFriendResultParser.ts | 36 + .../FindFriendsProcessResultParser.ts | 28 + .../friendlist/FollowFriendFailedParser.ts | 28 + .../FriendListFragmentMessageParser.ts | 53 + .../friendlist/FriendListUpdateParser.ts | 82 + .../friendlist/FriendNotificationParser.ts | 44 + .../parser/friendlist/FriendRequestsParser.ts | 45 + .../friendlist/HabboSearchResultParser.ts | 52 + .../friendlist/InstantMessageErrorParser.ts | 44 + .../parser/friendlist/MessageErrorParser.ts | 36 + .../parser/friendlist/MessengerInitParser.ts | 60 + .../friendlist/MiniMailNewMessageParser.ts | 17 + .../friendlist/MiniMailUnreadCountParser.ts | 28 + .../friendlist/NewConsoleMessageParser.ts | 56 + .../NewFriendRequestMessageParser.ts | 29 + .../friendlist/RoomInviteErrorParser.ts | 44 + .../friendlist/RoomInviteMessageParser.ts | 36 + .../messages/parser/game/LoadGameUrlParser.ts | 44 + .../parser/generic/GenericErrorParser.ts | 27 + .../parser/group/GroupBadgePartsParser.ts | 110 + .../parser/group/GroupBuyDataParser.ts | 46 + .../group/GroupConfirmMemberRemoveParser.ts | 36 + .../parser/group/GroupInformationParser.ts | 150 + .../parser/group/GroupMembersParser.ts | 117 + .../parser/group/GroupSettingsParser.ts | 150 + .../parser/group/utils/GroupBadgePart.ts | 22 + .../parser/group/utils/GroupDataParser.ts | 91 + .../parser/group/utils/GroupMemberParser.ts | 76 + .../help/CallForHelpResultMessageParser.ts | 36 + .../achievements/AchievementParser.ts | 29 + .../achievements/AchievementsParser.ts | 47 + .../achievements/AchievementsScoreParser.ts | 28 + .../AvatarEffectActivatedParser.ts | 44 + .../avatareffect/AvatarEffectAddedParser.ts | 52 + .../avatareffect/AvatarEffectExpiredParser.ts | 28 + .../AvatarEffectSelectedParser.ts | 28 + .../avatareffect/AvatarEffectsParser.ts | 45 + .../parser/inventory/badges/BadgesParser.ts | 71 + .../parser/inventory/badges/_Str_7305.ts | 46 + .../parser/inventory/badges/_Str_7446.ts | 25 + .../parser/inventory/badges/_Str_7491.ts | 36 + .../parser/inventory/badges/_Str_9135.ts | 33 + .../bots/BotAddedToInventoryParser.ts | 37 + .../messages/parser/inventory/bots/BotData.ts | 46 + .../bots/BotInventoryMessageParser.ts | 38 + .../bots/BotReceivedMessageParser.ts | 37 + .../bots/BotRemovedFromInventoryParser.ts | 28 + .../clothing/FigureSetIdsMessageParser.ts | 51 + .../parser/inventory/clothing/_Str_8728.ts | 28 + .../parser/inventory/clothing/_Str_9021.ts | 28 + .../furniture/FurnitureGiftOpenedParser.ts | 72 + .../FurnitureListAddOrUpdateParser.ts | 29 + .../FurnitureListInvalidateParser.ts | 17 + .../furniture/FurnitureListParser.ts | 55 + .../furniture/FurnitureListRemovedParser.ts | 28 + .../furniture/FurniturePostItPlacedParser.ts | 36 + .../utils/FurnitureListItemParser.ts | 219 + .../pets/PetAddedToInventoryParser.ts | 35 + .../PetBoughtNotificationMessageParser.ts | 32 + .../messages/parser/inventory/pets/PetData.ts | 70 + .../parser/inventory/pets/PetFigureData.ts | 73 + .../inventory/pets/PetInventoryParser.ts | 53 + .../pets/PetRemovedFromInventoryParser.ts | 26 + .../parser/inventory/pets/_Str_6256.ts | 36 + .../parser/inventory/pets/_Str_6719.ts | 83 + .../parser/inventory/pets/_Str_7486.ts | 26 + .../parser/inventory/pets/_Str_7523.ts | 48 + .../parser/inventory/pets/_Str_9220.ts | 34 + .../purse/UserCreditsMessageParser.ts | 26 + .../inventory/trading/TradingAcceptParser.ts | 36 + .../inventory/trading/TradingCloseParser.ts | 35 + .../trading/TradingCompletedParser.ts | 17 + .../trading/TradingConfirmationParser.ts | 17 + .../trading/TradingListItemParser.ts | 106 + .../inventory/trading/TradingNotOpenParser.ts | 17 + .../trading/TradingOpenFailedParser.ts | 36 + .../inventory/trading/TradingOpenParser.ts | 52 + .../trading/TradingOtherNotAllowedParser.ts | 17 + .../trading/TradingYouAreNotAllowedParser.ts | 17 + .../moderation/ModeratorMessageParser.ts | 36 + .../parser/modtool/ModtoolCFHTopicsParser.ts | 31 + .../parser/modtool/ModtoolMainParser.ts | 25 + .../modtool/ModtoolRoomChatlogParser.ts | 64 + .../parser/modtool/ModtoolRoomInfoParser.ts | 74 + .../parser/modtool/ModtoolRoomUsersParser.ts | 24 + .../modtool/ModtoolUserChatlogParser.ts | 76 + .../parser/modtool/ModtoolUserInfoParser.ts | 34 + .../modtool/utils/CallForHelpCategoryData.ts | 39 + .../messages/parser/modtool/utils/IChatlog.ts | 7 + .../modtool/utils/ModtoolRoomChatlogLine.ts | 39 + .../modtool/utils/ModtoolRoomVisitedData.ts | 39 + .../utils/ModtoolUserChatlogParserChatlog.ts | 44 + .../utils/ModtoolUserChatlogParserVisit.ts | 31 + .../utils/ModtoolUserVisitedRoomsRoom.ts | 37 + .../parser/modtool/utils/_Str_2484.ts | 159 + .../parser/modtool/utils/_Str_5018.ts | 138 + .../parser/modtool/utils/_Str_5460.ts | 50 + .../parser/modtool/utils/_Str_5467.ts | 145 + .../parser/modtool/utils/_Str_8176.ts | 45 + .../navigator/NavigatorCategoriesParser.ts | 36 + .../navigator/NavigatorCategoryDataParser.ts | 83 + .../navigator/NavigatorCollapsedParser.ts | 35 + .../NavigatorEventCategoriesParser.ts | 36 + .../NavigatorEventCategoryDataParser.ts | 51 + .../navigator/NavigatorHomeRoomParser.ts | 36 + .../navigator/NavigatorLiftedDataParser.ts | 59 + .../parser/navigator/NavigatorLiftedParser.ts | 36 + .../navigator/NavigatorMetadataParser.ts | 36 + .../NavigatorOpenRoomCreatorParser.ts | 17 + .../parser/navigator/NavigatorSearchParser.ts | 29 + .../navigator/NavigatorSearchesParser.ts | 36 + .../navigator/NavigatorSettingsParser.ts | 68 + .../navigator/utils/NavigatorSavedSearch.ts | 59 + .../utils/NavigatorSearchResultList.ts | 84 + .../utils/NavigatorSearchResultSet.ts | 60 + .../utils/NavigatorTopLevelContext.ts | 52 + .../notifications/BotErrorEventParser.ts | 27 + .../HabboBroadcastMessageParser.ts | 28 + .../notifications/HotelWillShutdownParser.ts | 28 + .../notifications/MOTDNotificationParser.ts | 35 + .../NotificationDialogMessageParser.ts | 44 + .../PetPlacingErrorEventParser.ts | 27 + .../notifications/RespectReceivedParser.ts | 36 + .../parser/notifications/UnseenItemsParser.ts | 53 + .../room/access/RoomEnterErrorParser.ts | 41 + .../parser/room/access/RoomEnterParser.ts | 17 + .../parser/room/access/RoomFowardParser.ts | 28 + .../doorbell/RoomDoorbellAcceptedParser.ts | 28 + .../access/doorbell/RoomDoorbellParser.ts | 28 + .../doorbell/RoomDoorbellRejectedParser.ts | 28 + .../access/rights/RoomRightsClearParser.ts | 17 + .../access/rights/RoomRightsOwnerParser.ts | 17 + .../room/access/rights/RoomRightsParser.ts | 29 + .../bots/BotCommandConfigurationParser.ts | 43 + .../parser/room/data/RoomChatParser.ts | 78 + .../room/data/RoomChatSettingsParser.ts | 29 + .../parser/room/data/RoomDataParser.ts | 311 ++ .../parser/room/data/RoomInfoOwnerParser.ts | 36 + .../parser/room/data/RoomInfoParser.ts | 76 + .../parser/room/data/RoomModerationParser.ts | 47 + .../parser/room/data/RoomScoreParser.ts | 36 + .../room/data/RoomSettingsErrorParser.ts | 44 + .../parser/room/data/RoomSettingsParser.ts | 163 + .../room/data/RoomSettingsSavedParser.ts | 28 + .../room/data/RoomSettingsUpdatedParser.ts | 28 + .../room/data/RoomSettingsUsersListParser.ts | 46 + .../room/engine/ObjectsRollingParser.ts | 82 + .../parser/room/engine/RoomCreatedParser.ts | 36 + .../room/furniture/FurnitureAliasesParser.ts | 35 + .../room/furniture/FurnitureDataParser.ts | 51 + .../room/furniture/FurnitureItemDataParser.ts | 36 + .../furniture/FurnitureStackHeightParser.ts | 36 + .../room/furniture/FurnitureState2Parser.ts | 36 + .../room/furniture/FurnitureStateParser.ts | 36 + .../furniture/LoveLockFurniFinishedParser.ts | 24 + .../LoveLockFurniFriendConfirmedParser.ts | 24 + .../furniture/LoveLockFurniStartParser.ts | 32 + .../RoomDimmerPresetsMessageParser.ts | 70 + .../floor/FurnitureFloorAddParser.ts | 30 + .../floor/FurnitureFloorDataParser.ts | 160 + .../furniture/floor/FurnitureFloorParser.ts | 69 + .../floor/FurnitureFloorRemoveParser.ts | 52 + .../floor/FurnitureFloorUpdateParser.ts | 29 + .../furniture/wall/FurnitureWallAddParser.ts | 30 + .../furniture/wall/FurnitureWallDataParser.ts | 228 ++ .../furniture/wall/FurnitureWallParser.ts | 69 + .../wall/FurnitureWallRemoveParser.ts | 36 + .../wall/FurnitureWallUpdateParser.ts | 30 + .../parser/room/mapping/RoomDoorParser.ts | 44 + .../room/mapping/RoomHeightMapParser.ts | 89 + .../room/mapping/RoomHeightMapUpdateParser.ts | 76 + .../room/mapping/RoomModelNameParser.ts | 36 + .../parser/room/mapping/RoomModelParser.ts | 167 + .../parser/room/mapping/RoomPaintParser.ts | 66 + .../room/mapping/RoomThicknessParser.ts | 51 + .../parser/room/pet/PetFigureUpdateParser.ts | 55 + .../messages/parser/room/pet/PetInfoParser.ts | 221 + .../room/session/YouArePlayingGameParser.ts | 28 + .../parser/room/unit/RoomUnitDanceParser.ts | 36 + .../parser/room/unit/RoomUnitEffectParser.ts | 44 + .../room/unit/RoomUnitExpressionParser.ts | 36 + .../room/unit/RoomUnitHandItemParser.ts | 36 + .../unit/RoomUnitHandItemReceivedParser.ts | 36 + .../parser/room/unit/RoomUnitIdleParser.ts | 36 + .../parser/room/unit/RoomUnitInfoParser.ts | 60 + .../parser/room/unit/RoomUnitNumberParser.ts | 36 + .../parser/room/unit/RoomUnitParser.ts | 188 + .../parser/room/unit/RoomUnitRemoveParser.ts | 28 + .../parser/room/unit/RoomUnitStatusAction.ts | 21 + .../parser/room/unit/RoomUnitStatusMessage.ts | 100 + .../parser/room/unit/RoomUnitStatusParser.ts | 120 + .../parser/room/unit/UserMessageData.ts | 412 ++ .../room/unit/chat/FloodControlParser.ts | 28 + .../room/unit/chat/RemainingMuteParser.ts | 28 + .../room/unit/chat/RoomUnitChatParser.ts | 88 + .../room/unit/chat/RoomUnitTypingParser.ts | 36 + .../parser/roomevents/RoomMutedParser.ts | 26 + .../roomevents/WiredFurniActionParser.ts | 29 + .../roomevents/WiredFurniConditionParser.ts | 29 + .../roomevents/WiredFurniTriggerParser.ts | 29 + .../parser/roomevents/WiredOpenParser.ts | 28 + .../WiredRewardResultMessageParser.ts | 28 + .../roomevents/WiredSaveSuccessParser.ts | 17 + .../roomevents/WiredValidationErrorParser.ts | 28 + .../parser/security/AuthenticatedParser.ts | 17 + .../parser/user/IgnoreResultParser.ts | 36 + .../parser/user/IgnoredUsersParser.ts | 37 + .../parser/user/InClientLinkParser.ts | 26 + .../parser/user/access/UserPerksParser.ts | 17 + .../user/access/UserPermissionsParser.ts | 44 + .../user/data/UserCurrentBadgesParser.ts | 47 + .../parser/user/data/UserFigureParser.ts | 36 + .../parser/user/data/UserInfoDataParser.ts | 139 + .../parser/user/data/UserInfoParser.ts | 31 + .../user/data/UserNameChangeMessageParser.ts | 44 + .../parser/user/data/UserProfileParser.ts | 125 + .../user/data/UserRelationshipDataParser.ts | 61 + .../user/data/UserRelationshipsParser.ts | 72 + .../parser/user/data/UserSettingsParser.ts | 84 + .../inventory/currency/UserCreditsParser.ts | 28 + .../inventory/currency/UserCurrencyParser.ts | 35 + .../currency/UserCurrencyUpdateParser.ts | 44 + .../subscription/UserSubscriptionParser.ts | 102 + .../user/wardrobe/UserWardrobePageParser.ts | 41 + src/nitro/enums/RelationshipStatusEnum.ts | 10 + src/nitro/enums/ToolbarIconEnum.ts | 10 + src/nitro/events/NitroSettingsEvent.ts | 100 + .../events/NitroToolbarAnimateIconEvent.ts | 34 + src/nitro/events/NitroToolbarEvent.ts | 35 + .../LegacyExternalInterface.ts | 91 + src/nitro/game/GameMessageHandler.ts | 22 + src/nitro/localization/BadgeBaseAndLevel.ts | 53 + .../localization/INitroLocalizationManager.ts | 13 + .../localization/NitroLocalizationEvent.ts | 12 + .../localization/NitroLocalizationManager.ts | 215 + src/nitro/room/IGetImageListener.ts | 7 + src/nitro/room/IRoomContentListener.ts | 4 + src/nitro/room/IRoomCreator.ts | 58 + src/nitro/room/IRoomEngine.ts | 103 + src/nitro/room/IRoomEngineServices.ts | 53 + src/nitro/room/ISelectedRoomObjectData.ts | 14 + src/nitro/room/ImageResult.ts | 18 + src/nitro/room/PetColorResult.ts | 59 + src/nitro/room/RoomContentLoader.ts | 765 ++++ src/nitro/room/RoomEngine.ts | 3641 +++++++++++++++++ src/nitro/room/RoomMessageHandler.ts | 968 +++++ src/nitro/room/RoomObjectEventHandler.ts | 2055 ++++++++++ src/nitro/room/RoomObjectLogicFactory.ts | 304 ++ src/nitro/room/RoomVariableEnum.ts | 14 + .../enums/FriendFurniEngravingWidgetType.ts | 8 + .../room/enums/RoomObjectPlacementSource.ts | 5 + .../room/events/RoomBackgroundColorEvent.ts | 34 + .../room/events/RoomEngineDimmerStateEvent.ts | 48 + src/nitro/room/events/RoomEngineEvent.ts | 26 + .../room/events/RoomEngineObjectEvent.ts | 37 + .../events/RoomEngineObjectPlacedEvent.ts | 74 + .../RoomEngineObjectPlacedOnUserEvent.ts | 25 + .../events/RoomEngineSamplePlaybackEvent.ts | 30 + .../events/RoomEngineTriggerWidgetEvent.ts | 50 + .../room/events/RoomObjectBadgeAssetEvent.ts | 28 + .../room/events/RoomObjectDataRequestEvent.ts | 13 + .../RoomObjectDimmerStateUpdateEvent.ts | 49 + .../room/events/RoomObjectFloorHoleEvent.ts | 13 + .../events/RoomObjectFurnitureActionEvent.ts | 20 + .../events/RoomObjectHSLColorEnableEvent.ts | 42 + .../events/RoomObjectHSLColorEnabledEvent.ts | 41 + src/nitro/room/events/RoomObjectMoveEvent.ts | 13 + .../events/RoomObjectSamplePlaybackEvent.ts | 31 + .../events/RoomObjectStateChangedEvent.ts | 22 + .../room/events/RoomObjectTileMouseEvent.ts | 48 + .../room/events/RoomObjectWallMouseEvent.ts | 61 + .../events/RoomObjectWidgetRequestEvent.ts | 45 + .../events/RoomToObjectOwnAvatarMoveEvent.ts | 21 + src/nitro/room/events/RoomZoomEvent.ts | 34 + .../room/messages/ObjectAdUpdateMessage.ts | 21 + .../ObjectAvatarCarryObjectUpdateMessage.ts | 25 + .../messages/ObjectAvatarChatUpdateMessage.ts | 18 + .../ObjectAvatarDanceUpdateMessage.ts | 18 + .../ObjectAvatarEffectUpdateMessage.ts | 25 + .../ObjectAvatarExperienceUpdateMessage.ts | 18 + .../ObjectAvatarExpressionUpdateMessage.ts | 18 + .../ObjectAvatarFigureUpdateMessage.ts | 39 + .../ObjectAvatarFlatControlUpdateMessage.ts | 18 + .../ObjectAvatarGestureUpdateMessage.ts | 18 + .../ObjectAvatarGuideStatusUpdateMessage.ts | 18 + .../ObjectAvatarMutedUpdateMessage.ts | 18 + .../room/messages/ObjectAvatarOwnMessage.ts | 4 + .../ObjectAvatarPetGestureUpdateMessage.ts | 18 + .../ObjectAvatarPlayerValueUpdateMessage.ts | 18 + .../ObjectAvatarPlayingGameUpdateMessage.ts | 18 + .../ObjectAvatarPostureUpdateMessage.ts | 25 + .../messages/ObjectAvatarSelectedMessage.ts | 18 + .../messages/ObjectAvatarSignUpdateMessage.ts | 18 + .../ObjectAvatarSleepUpdateMessage.ts | 18 + .../ObjectAvatarTypingUpdateMessage.ts | 18 + .../messages/ObjectAvatarUpdateMessage.ts | 33 + .../ObjectAvatarUseObjectUpdateMessage.ts | 18 + .../room/messages/ObjectDataUpdateMessage.ts | 33 + .../messages/ObjectGroupBadgeUpdateMessage.ts | 27 + .../messages/ObjectHeightUpdateMessage.ts | 19 + .../messages/ObjectItemDataUpdateMessage.ts | 18 + .../messages/ObjectModelDataUpdateMessage.ts | 25 + .../room/messages/ObjectMoveUpdateMessage.ts | 28 + .../messages/ObjectRoomColorUpdateMessage.ts | 41 + .../ObjectRoomFloorHoleUpdateMessage.ts | 56 + .../messages/ObjectRoomMapUpdateMessage.ts | 28 + .../messages/ObjectRoomMaskUpdateMessage.ts | 54 + .../ObjectRoomPlanePropertyUpdateMessage.ts | 28 + .../ObjectRoomPlaneVisibilityUpdateMessage.ts | 28 + .../room/messages/ObjectRoomUpdateMessage.ts | 29 + .../room/messages/ObjectSelectedMessage.ts | 18 + .../room/messages/ObjectStateUpdateMessage.ts | 9 + .../messages/ObjectTileCursorUpdateMessage.ts | 40 + .../messages/ObjectVisibilityUpdateMessage.ts | 21 + src/nitro/room/object/RoomFloorHole.ts | 35 + src/nitro/room/object/RoomMapData.ts | 125 + src/nitro/room/object/RoomMapMaskData.ts | 16 + src/nitro/room/object/RoomObjectCategory.ts | 9 + src/nitro/room/object/RoomObjectLogicType.ts | 74 + .../room/object/RoomObjectOperationType.ts | 15 + src/nitro/room/object/RoomObjectType.ts | 7 + src/nitro/room/object/RoomObjectUserType.ts | 40 + src/nitro/room/object/RoomObjectVariable.ts | 138 + .../object/RoomObjectVisualizationFactory.ts | 271 ++ .../object/RoomObjectVisualizationType.ts | 39 + .../room/object/RoomPlaneBitmapMaskData.ts | 56 + .../room/object/RoomPlaneBitmapMaskParser.ts | 147 + src/nitro/room/object/RoomPlaneData.ts | 202 + src/nitro/room/object/RoomPlaneMaskData.ts | 35 + src/nitro/room/object/RoomPlaneParser.ts | 1700 ++++++++ src/nitro/room/object/RoomWallData.ts | 182 + src/nitro/room/object/data/IObjectData.ts | 16 + src/nitro/room/object/data/ObjectDataBase.ts | 84 + .../room/object/data/ObjectDataFactory.ts | 51 + src/nitro/room/object/data/ObjectDataFlags.ts | 4 + src/nitro/room/object/data/ObjectDataKey.ts | 11 + .../object/data/type/CrackableDataType.ts | 74 + .../room/object/data/type/EmptyDataType.ts | 39 + .../room/object/data/type/HighScoreData.ts | 36 + .../object/data/type/HighScoreDataType.ts | 121 + .../room/object/data/type/LegacyDataType.ts | 59 + .../room/object/data/type/MapDataType.ts | 79 + .../room/object/data/type/NumberDataType.ts | 91 + .../room/object/data/type/StringDataType.ts | 90 + .../room/object/data/type/VoteDataType.ts | 66 + .../room/object/logic/MovingObjectLogic.ts | 143 + .../room/object/logic/avatar/AvatarLogic.ts | 528 +++ .../furniture/FurnitureBadgeDisplayLogic.ts | 78 + .../FurnitureChangeStateWhenStepOnLogic.ts | 54 + .../furniture/FurnitureCounterClockLogic.ts | 54 + .../furniture/FurnitureCrackableLogic.ts | 19 + .../logic/furniture/FurnitureCreditLogic.ts | 49 + .../FurnitureCustomStackHeightLogic.ts | 19 + .../logic/furniture/FurnitureDiceLogic.ts | 72 + .../FurnitureEditableInternalLinkLogic.ts | 83 + .../FurnitureEditableRoomLinkLogic.ts | 74 + .../furniture/FurnitureExternalImageLogic.ts | 46 + .../furniture/FurnitureFireworksLogic.ts | 6 + .../furniture/FurnitureFloorHoleLogic.ts | 110 + .../logic/furniture/FurnitureFriendLogic.ts | 72 + .../FurnitureGuildCustomizedLogic.ts | 46 + .../furniture/FurnitureHabboWheelLogic.ts | 40 + .../furniture/FurnitureHighScoreLogic.ts | 65 + .../furniture/FurnitureHockeyScoreLogic.ts | 62 + .../logic/furniture/FurnitureIceStormLogic.ts | 65 + .../object/logic/furniture/FurnitureLogic.ts | 374 ++ .../furniture/FurnitureMannequinLogic.ts | 69 + .../furniture/FurnitureMultiHeightLogic.ts | 13 + .../furniture/FurnitureMultiStateLogic.ts | 32 + .../furniture/FurnitureOneWayDoorLogic.ts | 37 + .../FurniturePetCustomizationLogic.ts | 6 + .../logic/furniture/FurniturePresentLogic.ts | 114 + .../FurniturePurchaseableClothingLogic.ts | 20 + .../logic/furniture/FurniturePushableLogic.ts | 6 + .../FurnitureRoomBackgroundColorLogic.ts | 110 + .../furniture/FurnitureRoomBackgroundLogic.ts | 10 + .../furniture/FurnitureRoomBillboardLogic.ts | 18 + .../furniture/FurnitureRoomBrandingLogic.ts | 145 + .../furniture/FurnitureRoomDimmerLogic.ts | 140 + .../logic/furniture/FurnitureScoreLogic.ts | 71 + .../furniture/FurnitureSoundBlockLogic.ts | 131 + .../logic/furniture/FurnitureStickieLogic.ts | 78 + .../logic/furniture/FurnitureTrophyLogic.ts | 36 + .../furniture/FurnitureVoteCounterLogic.ts | 97 + .../furniture/FurnitureVoteMajorityLogic.ts | 22 + .../logic/furniture/FurnitureWindowLogic.ts | 18 + .../logic/furniture/FurnitureYoutubeLogic.ts | 31 + src/nitro/room/object/logic/pet/PetLogic.ts | 242 ++ src/nitro/room/object/logic/room/RoomLogic.ts | 459 +++ .../object/logic/room/SelectionArrowLogic.ts | 37 + .../room/object/logic/room/TileCursorLogic.ts | 66 + .../avatar/AvatarVisualization.ts | 1115 +++++ .../avatar/AvatarVisualizationData.ts | 61 + .../avatar/additions/ExpressionAddition.ts | 47 + .../additions/ExpressionAdditionFactory.ts | 22 + .../avatar/additions/FloatingHeartAddition.ts | 169 + .../avatar/additions/FloatingIdleZAddition.ts | 162 + .../avatar/additions/IAvatarAddition.ts | 9 + .../avatar/additions/IExpressionAddition.ts | 6 + .../avatar/additions/MutedBubbleAddition.ts | 80 + .../avatar/additions/NumberBubbleAddition.ts | 183 + .../avatar/additions/TypingBubbleAddition.ts | 99 + .../visualization/data/AnimationData.ts | 191 + .../visualization/data/AnimationFrame.ts | 118 + .../visualization/data/AnimationFrameData.ts | 64 + .../data/AnimationFrameDirectionalData.ts | 33 + .../data/AnimationFrameSequenceData.ts | 111 + .../visualization/data/AnimationLayerData.ts | 156 + .../visualization/data/AnimationSizeData.ts | 158 + .../visualization/data/AnimationStateData.ts | 184 + .../object/visualization/data/ColorData.ts | 43 + .../visualization/data/DirectionData.ts | 196 + .../data/DirectionalOffsetData.ts | 35 + .../object/visualization/data/LayerData.ts | 120 + .../object/visualization/data/PetSizeData.ts | 143 + .../object/visualization/data/SizeData.ts | 284 ++ .../FurnitureAnimatedVisualization.ts | 407 ++ .../FurnitureAnimatedVisualizationData.ts | 92 + .../furniture/FurnitureBBVisualization.ts | 19 + .../FurnitureBadgeDisplayVisualization.ts | 92 + .../furniture/FurnitureBottleVisualization.ts | 62 + .../FurnitureBrandedImageVisualization.ts | 162 + ...urnitureBuilderPlaceholderVisualization.ts | 6 + .../FurnitureCounterClockVisualization.ts | 29 + .../furniture/FurnitureCuboidVisualization.ts | 6 + .../FurnitureDynamicThumbnailVisualization.ts | 55 + .../FurnitureExternalImageVisualization.ts | 50 + .../FurnitureFireworksVisualization.ts | 6 + ...nitureGiftWrappedFireworksVisualization.ts | 79 + .../FurnitureGiftWrappedVisualization.ts | 61 + .../FurnitureGuildCustomizedVisualization.ts | 44 + ...rnitureGuildIsometricBadgeVisualization.ts | 6 + .../FurnitureHabboWheelVisualization.ts | 64 + .../FurnitureMannequinVisualization.ts | 174 + .../FurnitureMannequinVisualizationData.ts | 40 + .../FurnitureParticleSystemEmitter.ts | 276 ++ .../FurnitureParticleSystemParticle.ts | 200 + .../FurniturePartyBeamerVisualization.ts | 6 + .../FurniturePlanetSystemVisualization.ts | 6 + .../furniture/FurniturePosterVisualization.ts | 6 + .../FurnitureQueueTileVisualization.ts | 50 + ...FurnitureResettingAnimatedVisualization.ts | 9 + .../FurnitureRoomBackgroundVisualization.ts | 59 + .../FurnitureScoreBoardVisualization.ts | 24 + .../FurnitureSoundBlockVisualization.ts | 6 + .../FurnitureStickieVisualization.ts | 12 + .../FurnitureThumbnailVisualization.ts | 150 + .../FurnitureValRandomizerVisualization.ts | 76 + .../furniture/FurnitureVisualization.ts | 583 +++ .../furniture/FurnitureVisualizationData.ts | 295 ++ .../FurnitureVoteCounterVisualization.ts | 51 + .../FurnitureVoteMajorityVisualization.ts | 45 + .../FurnitureWaterAreaVisualization.ts | 6 + .../FurnitureYoutubeVisualization.ts | 20 + .../visualization/pet/PetVisualization.ts | 561 +++ .../visualization/pet/PetVisualizationData.ts | 127 + .../visualization/room/PlaneDrawingData.ts | 103 + .../object/visualization/room/RoomPlane.ts | 1021 +++++ .../visualization/room/RoomPlaneBitmapMask.ts | 28 + .../room/RoomPlaneRectangleMask.ts | 35 + .../visualization/room/RoomVisualization.ts | 1015 +++++ .../room/RoomVisualizationData.ts | 127 + .../room/TileCursorVisualization.ts | 26 + .../visualization/room/mask/PlaneMask.ts | 118 + .../room/mask/PlaneMaskBitmap.ts | 52 + .../room/mask/PlaneMaskManager.ts | 196 + .../room/mask/PlaneMaskVisualization.ts | 50 + .../room/rasterizer/IPlaneRasterizer.ts | 13 + .../room/rasterizer/animated/AnimationItem.ts | 53 + .../rasterizer/animated/LandscapePlane.ts | 62 + .../animated/LandscapeRasterizer.ts | 247 ++ .../PlaneVisualizationAnimationLayer.ts | 151 + .../room/rasterizer/basic/FloorPlane.ts | 38 + .../room/rasterizer/basic/FloorRasterizer.ts | 65 + .../room/rasterizer/basic/Plane.ts | 112 + .../room/rasterizer/basic/PlaneMaterial.ts | 93 + .../rasterizer/basic/PlaneMaterialCell.ts | 242 ++ .../basic/PlaneMaterialCellColumn.ts | 490 +++ .../basic/PlaneMaterialCellMatrix.ts | 723 ++++ .../room/rasterizer/basic/PlaneRasterizer.ts | 609 +++ .../room/rasterizer/basic/PlaneTexture.ts | 66 + .../rasterizer/basic/PlaneTextureBitmap.ts | 59 + .../rasterizer/basic/PlaneVisualization.ts | 240 ++ .../basic/PlaneVisualizationLayer.ts | 147 + .../room/rasterizer/basic/WallPlane.ts | 30 + .../room/rasterizer/basic/WallRasterizer.ts | 76 + .../room/utils/PlaneBitmapData.ts | 28 + .../visualization/room/utils/Randomizer.ts | 126 + src/nitro/room/preview/RoomPreviewer.ts | 853 ++++ src/nitro/room/utils/FurnitureData.ts | 120 + .../room/utils/FurnitureStackingHeightMap.ts | 119 + src/nitro/room/utils/LegacyWallGeometry.ts | 324 ++ src/nitro/room/utils/ObjectRolling.ts | 40 + src/nitro/room/utils/RoomCamera.ts | 288 ++ src/nitro/room/utils/RoomData.ts | 59 + src/nitro/room/utils/RoomInstanceData.ts | 235 ++ .../RoomObjectBadgeImageAssetListener.ts | 23 + .../room/utils/SelectedRoomObjectData.ts | 97 + src/nitro/room/utils/SpriteDataCollector.ts | 460 +++ src/nitro/room/utils/TileObjectMap.ts | 123 + src/nitro/session/BadgeImageManager.ts | 107 + src/nitro/session/BadgeInfo.ts | 23 + src/nitro/session/HabboClubLevelEnum.ts | 6 + src/nitro/session/IRoomHandlerListener.ts | 10 + src/nitro/session/IRoomSession.ts | 51 + src/nitro/session/IRoomSessionManager.ts | 13 + src/nitro/session/ISessionDataManager.ts | 54 + src/nitro/session/IgnoredUsersManager.ts | 130 + src/nitro/session/RoomPetData.ts | 295 ++ src/nitro/session/RoomSession.ts | 389 ++ src/nitro/session/RoomSessionManager.ts | 242 ++ src/nitro/session/RoomUserData.ts | 256 ++ src/nitro/session/SessionDataManager.ts | 647 +++ src/nitro/session/UserDataManager.ts | 192 + src/nitro/session/enum/GenericErrorEnum.ts | 5 + src/nitro/session/enum/RoomControllerLevel.ts | 9 + .../session/enum/RoomTradingLevelEnum.ts | 22 + src/nitro/session/enum/SecurityLevel.ts | 13 + .../session/events/BadgeImageReadyEvent.ts | 28 + .../events/MysteryBoxKeysUpdateEvent.ts | 27 + src/nitro/session/events/PerksUpdatedEvent.ts | 11 + .../session/events/RoomSessionChatEvent.ts | 69 + .../RoomSessionConfirmPetBreedingEvent.ts | 49 + ...oomSessionConfirmPetBreedingResultEvent.ts | 28 + .../session/events/RoomSessionDanceEvent.ts | 28 + .../events/RoomSessionDimmerPresetsEvent.ts | 48 + ...RoomSessionDimmerPresetsEventPresetItem.ts | 35 + .../events/RoomSessionDoorbellEvent.ts | 23 + .../events/RoomSessionErrorMessageEvent.ts | 32 + src/nitro/session/events/RoomSessionEvent.ts | 31 + .../RoomSessionFavouriteGroupUpdateEvent.ts | 42 + .../events/RoomSessionFriendRequestEvent.ts | 35 + .../RoomSessionNestBreedingSuccessEvent.ts | 28 + .../events/RoomSessionPetBreedingEvent.ts | 35 + .../RoomSessionPetBreedingResultEvent.ts | 28 + .../RoomSessionPetCommandsUpdateEvent.ts | 35 + .../events/RoomSessionPetFigureUpdateEvent.ts | 28 + .../events/RoomSessionPetInfoUpdateEvent.ts | 22 + .../events/RoomSessionPetLevelUpdateEvent.ts | 28 + .../events/RoomSessionPetPackageEvent.ts | 43 + .../events/RoomSessionPetStatusUpdateEvent.ts | 49 + .../session/events/RoomSessionPollEvent.ts | 49 + .../session/events/RoomSessionPresentEvent.ts | 64 + .../events/RoomSessionPropertyUpdateEvent.ts | 12 + .../session/events/RoomSessionQueueEvent.ts | 57 + .../events/RoomSessionUserBadgesEvent.ts | 29 + .../events/RoomSessionUserDataUpdateEvent.ts | 22 + .../RoomSessionUserFigureUpdateEvent.ts | 48 + .../events/RoomSessionUserTagsEvent.ts | 27 + .../events/RoomSessionWordQuizEvent.ts | 111 + .../events/SessionDataPreferencesEvent.ts | 20 + .../session/events/UserNameUpdateEvent.ts | 20 + src/nitro/session/events/_Str_3051.ts | 100 + src/nitro/session/furniture/FurnitureData.ts | 222 + .../session/furniture/FurnitureDataParser.ts | 136 + src/nitro/session/furniture/FurnitureType.ts | 10 + src/nitro/session/furniture/IFurnitureData.ts | 33 + .../furniture/IFurnitureDataListener.ts | 4 + src/nitro/session/handler/BaseHandler.ts | 45 + .../session/handler/GenericErrorHandler.ts | 44 + src/nitro/session/handler/RoomChatHandler.ts | 116 + src/nitro/session/handler/RoomDataHandler.ts | 42 + .../handler/RoomDimmerPresetsHandler.ts | 48 + .../session/handler/RoomPermissionsHandler.ts | 52 + .../session/handler/RoomPresentHandler.ts | 36 + .../session/handler/RoomSessionHandler.ts | 109 + src/nitro/session/handler/RoomUsersHandler.ts | 332 ++ src/nitro/session/product/IProductData.ts | 6 + .../session/product/IProductDataListener.ts | 6 + src/nitro/session/product/ProductData.ts | 30 + .../session/product/ProductDataParser.ts | 57 + src/nitro/ui/IRoomWidgetHandler.ts | 16 + src/nitro/ui/IRoomWidgetHandlerContainer.ts | 27 + src/nitro/ui/MouseEventType.ts | 10 + src/nitro/ui/TouchEventType.ts | 7 + .../ui/widget/ConversionTrackingWidget.ts | 85 + src/nitro/ui/widget/IRoomWidget.ts | 13 + .../ui/widget/IRoomWidgetMessageListener.ts | 7 + .../ui/widget/enums/AvatarExpressionEnum.ts | 28 + .../FriendWidgetEngravingWidgetTypeEnum.ts | 8 + src/nitro/ui/widget/enums/RoomWidgetEnum.ts | 57 + .../RoomWidgetEnumItemExtradataParameter.ts | 10 + .../RoomWidgetFurniInfoUsagePolicyEnum.ts | 6 + .../ui/widget/enums/SystemChatStyleEnum.ts | 6 + .../ui/widget/events/RoomWidgetUpdateEvent.ts | 9 + .../ui/widget/messages/RoomWidgetMessage.ts | 14 + src/nitro/utils/FigureDataContainer.ts | 241 ++ src/nitro/utils/FixedSizeStack.ts | 65 + src/nitro/utils/FriendlyTime.ts | 47 + src/nitro/utils/FurniId.ts | 9 + src/nitro/utils/HabboWebTools.ts | 333 ++ src/nitro/utils/WebGL.ts | 9 + src/nitro/window/motion/Callback.ts | 30 + src/nitro/window/motion/Combo.ts | 61 + src/nitro/window/motion/Dispose.ts | 21 + src/nitro/window/motion/DropBounce.ts | 60 + src/nitro/window/motion/Ease.ts | 34 + src/nitro/window/motion/EaseOut.ts | 15 + src/nitro/window/motion/EaseRate.ts | 14 + src/nitro/window/motion/Interval.ts | 47 + src/nitro/window/motion/JumpBy.ts | 37 + src/nitro/window/motion/Motion.ts | 61 + src/nitro/window/motion/Motions.ts | 193 + src/nitro/window/motion/MoveBy.ts | 17 + src/nitro/window/motion/MoveTo.ts | 35 + src/nitro/window/motion/Queue.ts | 71 + src/nitro/window/motion/ResizeTo.ts | 35 + src/nitro/window/motion/Wait.ts | 37 + src/room/IRoomInstance.ts | 28 + src/room/IRoomInstanceContainer.ts | 8 + src/room/IRoomManager.ts | 19 + src/room/IRoomManagerListener.ts | 6 + src/room/IRoomObjectManager.ts | 14 + src/room/RoomInstance.ts | 300 ++ src/room/RoomManager.ts | 412 ++ src/room/RoomObjectManager.ts | 131 + src/room/data/RoomObjectSpriteData.ts | 18 + src/room/events/RoomContentLoadedEvent.ts | 22 + src/room/events/RoomObjectEvent.ts | 33 + src/room/events/RoomObjectMouseEvent.ts | 99 + src/room/events/RoomSpriteMouseEvent.ts | 115 + src/room/events/RoomToObjectEvent.ts | 9 + src/room/messages/RoomObjectUpdateMessage.ts | 23 + src/room/object/IRoomObject.ts | 22 + src/room/object/IRoomObjectController.ts | 18 + src/room/object/IRoomObjectModel.ts | 8 + src/room/object/IRoomObjectModelController.ts | 11 + src/room/object/RoomObject.ts | 252 ++ src/room/object/RoomObjectModel.ts | 48 + src/room/object/enum/AlphaTolerance.ts | 6 + src/room/object/enum/RoomObjectSpriteType.ts | 7 + .../object/logic/IRoomObjectEventHandler.ts | 20 + .../object/logic/IRoomObjectLogicFactory.ts | 10 + .../object/logic/IRoomObjectMouseHandler.ts | 7 + src/room/object/logic/RoomObjectLogicBase.ts | 136 + .../object/visualization/IPlaneDrawingData.ts | 14 + .../visualization/IPlaneVisualization.ts | 6 + .../IRoomObjectGraphicVisualization.ts | 7 + .../object/visualization/IRoomObjectSprite.ts | 32 + .../IRoomObjectSpriteVisualization.ts | 12 + .../visualization/IRoomObjectVisualization.ts | 17 + .../IRoomObjectVisualizationData.ts | 7 + .../IRoomObjectVisualizationFactory.ts | 9 + src/room/object/visualization/IRoomPlane.ts | 13 + .../object/visualization/ISortableSprite.ts | 9 + .../object/visualization/RoomObjectSprite.ts | 422 ++ .../RoomObjectSpriteVisualization.ts | 309 ++ .../visualization/utils/GraphicAsset.ts | 140 + .../utils/GraphicAssetCollection.ts | 372 ++ .../utils/GraphicAssetPalette.ts | 58 + .../visualization/utils/IGraphicAsset.ts | 18 + .../utils/IGraphicAssetCollection.ts | 23 + src/room/renderer/IRoomCanvasMouseListener.ts | 8 + src/room/renderer/IRoomRenderer.ts | 9 + src/room/renderer/IRoomRendererBase.ts | 10 + src/room/renderer/IRoomRendererFactory.ts | 6 + src/room/renderer/IRoomRenderingCanvas.ts | 33 + .../renderer/IRoomSpriteCanvasContainer.ts | 8 + src/room/renderer/RoomRenderer.ts | 172 + src/room/renderer/RoomRendererFactory.ts | 11 + src/room/renderer/RoomSpriteCanvas.ts | 1083 +++++ src/room/renderer/cache/RoomObjectCache.ts | 148 + .../renderer/cache/RoomObjectCacheItem.ts | 52 + .../cache/RoomObjectLocationCacheItem.ts | 98 + .../RoomObjectSortableSpriteCacheItem.ts | 78 + src/room/renderer/utils/ExtendedSprite.ts | 241 ++ src/room/renderer/utils/ObjectMouseData.ts | 31 + src/room/renderer/utils/SortableSprite.ts | 80 + src/room/utils/ColorConverter.ts | 324 ++ src/room/utils/IRoomGeometry.ts | 21 + src/room/utils/IVector3D.ts | 7 + src/room/utils/NumberBank.ts | 54 + src/room/utils/PointMath.ts | 19 + src/room/utils/Rasterizer.ts | 129 + src/room/utils/RoomEnterEffect.ts | 78 + src/room/utils/RoomGeometry.ts | 433 ++ src/room/utils/RoomId.ts | 14 + src/room/utils/SpriteUtilities.ts | 16 + src/room/utils/TextureUtils.ts | 47 + src/room/utils/Vector3d.ts | 187 + tsconfig.json | 20 + 1330 files changed, 90698 insertions(+) create mode 100644 .browserslistrc create mode 100644 .editorconfig create mode 100644 .eslintrc.json create mode 100644 .gitignore create mode 100644 .gitlab-ci.yml create mode 100644 .vscode/settings.json create mode 100644 LICENSE create mode 100644 index.ts create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 src/core/INitroCore.ts create mode 100644 src/core/NitroCore.ts create mode 100644 src/core/asset/AssetManager.ts create mode 100644 src/core/asset/IAssetManager.ts create mode 100644 src/core/asset/NitroBundle.ts create mode 100644 src/core/asset/index.ts create mode 100644 src/core/asset/interfaces/IAsset.ts create mode 100644 src/core/asset/interfaces/IAssetAlias.ts create mode 100644 src/core/asset/interfaces/IAssetData.ts create mode 100644 src/core/asset/interfaces/IAssetDimension.ts create mode 100644 src/core/asset/interfaces/IAssetPalette.ts create mode 100644 src/core/asset/interfaces/animation/IAssetAnimation.ts create mode 100644 src/core/asset/interfaces/animation/IAssetAnimationAdd.ts create mode 100644 src/core/asset/interfaces/animation/IAssetAnimationAvatar.ts create mode 100644 src/core/asset/interfaces/animation/IAssetAnimationDirection.ts create mode 100644 src/core/asset/interfaces/animation/IAssetAnimationFrame.ts create mode 100644 src/core/asset/interfaces/animation/IAssetAnimationFramePart.ts create mode 100644 src/core/asset/interfaces/animation/IAssetAnimationFramePartItem.ts create mode 100644 src/core/asset/interfaces/animation/IAssetAnimationOverride.ts create mode 100644 src/core/asset/interfaces/animation/IAssetAnimationRemove.ts create mode 100644 src/core/asset/interfaces/animation/IAssetAnimationShadow.ts create mode 100644 src/core/asset/interfaces/animation/IAssetAnimationSprite.ts create mode 100644 src/core/asset/interfaces/animation/IAssetAnimationSpriteDirection.ts create mode 100644 src/core/asset/interfaces/animation/index.ts create mode 100644 src/core/asset/interfaces/index.ts create mode 100644 src/core/asset/interfaces/spritesheet/ISpritesheetData.ts create mode 100644 src/core/asset/interfaces/spritesheet/ISpritesheetFrame.ts create mode 100644 src/core/asset/interfaces/spritesheet/ISpritesheetMeta.ts create mode 100644 src/core/asset/interfaces/spritesheet/index.ts create mode 100644 src/core/asset/interfaces/visualization/IAssetVisualizationData.ts create mode 100644 src/core/asset/interfaces/visualization/IAssetVisualizationDirection.ts create mode 100644 src/core/asset/interfaces/visualization/IAssetVisualizationLayer.ts create mode 100644 src/core/asset/interfaces/visualization/animation/IAssetVisualAnimation.ts create mode 100644 src/core/asset/interfaces/visualization/animation/IAssetVisualAnimationLayer.ts create mode 100644 src/core/asset/interfaces/visualization/animation/IAssetVisualAnimationSequence.ts create mode 100644 src/core/asset/interfaces/visualization/animation/IAssetVisualAnimationSequenceFrame.ts create mode 100644 src/core/asset/interfaces/visualization/animation/IAssetVisualAnimationSequenceFrameOffset.ts create mode 100644 src/core/asset/interfaces/visualization/animation/index.ts create mode 100644 src/core/asset/interfaces/visualization/color/IAssetColor.ts create mode 100644 src/core/asset/interfaces/visualization/color/IAssetColorLayer.ts create mode 100644 src/core/asset/interfaces/visualization/color/index.ts create mode 100644 src/core/asset/interfaces/visualization/gestures/IAssetGesture.ts create mode 100644 src/core/asset/interfaces/visualization/gestures/index.ts create mode 100644 src/core/asset/interfaces/visualization/index.ts create mode 100644 src/core/asset/interfaces/visualization/postures/IAssetPosture.ts create mode 100644 src/core/asset/interfaces/visualization/postures/index.ts create mode 100644 src/core/common/INitroManager.ts create mode 100644 src/core/common/IUpdateReceiver.ts create mode 100644 src/core/common/NitroManager.ts create mode 100644 src/core/common/disposable/Disposable.ts create mode 100644 src/core/common/disposable/IDisposable.ts create mode 100644 src/core/common/disposable/index.ts create mode 100644 src/core/common/index.ts create mode 100644 src/core/common/logger/INitroLogger.ts create mode 100644 src/core/common/logger/NitroLogger.ts create mode 100644 src/core/common/logger/index.ts create mode 100644 src/core/communication/CommunicationManager.ts create mode 100644 src/core/communication/ICommunicationManager.ts create mode 100644 src/core/communication/codec/BinaryReader.ts create mode 100644 src/core/communication/codec/BinaryWriter.ts create mode 100644 src/core/communication/codec/Byte.ts create mode 100644 src/core/communication/codec/ICodec.ts create mode 100644 src/core/communication/codec/Short.ts create mode 100644 src/core/communication/codec/evawire/EvaWireDataWrapper.ts create mode 100644 src/core/communication/codec/evawire/EvaWireFormat.ts create mode 100644 src/core/communication/codec/evawire/index.ts create mode 100644 src/core/communication/codec/index.ts create mode 100644 src/core/communication/connections/IConnection.ts create mode 100644 src/core/communication/connections/IConnectionStateListener.ts create mode 100644 src/core/communication/connections/SocketConnection.ts create mode 100644 src/core/communication/connections/enums/ClientDeviceCategoryEnum.ts create mode 100644 src/core/communication/connections/enums/ClientPlatformEnum.ts create mode 100644 src/core/communication/connections/enums/WebSocketEventEnum.ts create mode 100644 src/core/communication/connections/enums/index.ts create mode 100644 src/core/communication/connections/index.ts create mode 100644 src/core/communication/events/SocketConnectionEvent.ts create mode 100644 src/core/communication/events/index.ts create mode 100644 src/core/communication/index.ts create mode 100644 src/core/communication/messages/IMessageComposer.ts create mode 100644 src/core/communication/messages/IMessageConfiguration.ts create mode 100644 src/core/communication/messages/IMessageDataWrapper.ts create mode 100644 src/core/communication/messages/IMessageEvent.ts create mode 100644 src/core/communication/messages/IMessageParser.ts create mode 100644 src/core/communication/messages/MessageClassManager.ts create mode 100644 src/core/communication/messages/MessageEvent.ts create mode 100644 src/core/communication/messages/index.ts create mode 100644 src/core/configuration/ConfigurationEvent.ts create mode 100644 src/core/configuration/ConfigurationManager.ts create mode 100644 src/core/configuration/IConfigurationManager.ts create mode 100644 src/core/configuration/index.ts create mode 100644 src/core/events/EventDispatcher.ts create mode 100644 src/core/events/IEventDispatcher.ts create mode 100644 src/core/events/ILinkEventTracker.ts create mode 100644 src/core/events/IWorkerEventTracker.ts create mode 100644 src/core/events/NitroEvent.ts create mode 100644 src/core/events/index.ts create mode 100644 src/core/index.ts create mode 100644 src/core/utils/AdvancedMap.ts create mode 100644 src/core/utils/NitroTimer.ts create mode 100644 src/core/utils/index.ts create mode 100644 src/index.ts create mode 100644 src/nitro/INitro.ts create mode 100644 src/nitro/Nitro.ts create mode 100644 src/nitro/avatar/AvatarAssetDownloadLibrary.ts create mode 100644 src/nitro/avatar/AvatarAssetDownloadManager.ts create mode 100644 src/nitro/avatar/AvatarFigureContainer.ts create mode 100644 src/nitro/avatar/AvatarImage.ts create mode 100644 src/nitro/avatar/AvatarImageBodyPartContainer.ts create mode 100644 src/nitro/avatar/AvatarImagePartContainer.ts create mode 100644 src/nitro/avatar/AvatarRenderManager.ts create mode 100644 src/nitro/avatar/AvatarStructure.ts create mode 100644 src/nitro/avatar/EffectAssetDownloadLibrary.ts create mode 100644 src/nitro/avatar/EffectAssetDownloadManager.ts create mode 100644 src/nitro/avatar/IAvatarEffectListener.ts create mode 100644 src/nitro/avatar/IAvatarFigureContainer.ts create mode 100644 src/nitro/avatar/IAvatarImage.ts create mode 100644 src/nitro/avatar/IAvatarImageListener.ts create mode 100644 src/nitro/avatar/IAvatarRenderManager.ts create mode 100644 src/nitro/avatar/IOutfit.ts create mode 100644 src/nitro/avatar/PlaceHolderAvatarImage.ts create mode 100644 src/nitro/avatar/actions/ActionDefinition.ts create mode 100644 src/nitro/avatar/actions/ActionType.ts create mode 100644 src/nitro/avatar/actions/ActiveActionData.ts create mode 100644 src/nitro/avatar/actions/AvatarActionManager.ts create mode 100644 src/nitro/avatar/actions/IActionDefinition.ts create mode 100644 src/nitro/avatar/actions/IActiveActionData.ts create mode 100644 src/nitro/avatar/alias/AssetAlias.ts create mode 100644 src/nitro/avatar/alias/AssetAliasCollection.ts create mode 100644 src/nitro/avatar/animation/AddDataContainer.ts create mode 100644 src/nitro/avatar/animation/Animation.ts create mode 100644 src/nitro/avatar/animation/AnimationLayerData.ts create mode 100644 src/nitro/avatar/animation/AnimationManager.ts create mode 100644 src/nitro/avatar/animation/AvatarDataContainer.ts create mode 100644 src/nitro/avatar/animation/DirectionDataContainer.ts create mode 100644 src/nitro/avatar/animation/IAnimation.ts create mode 100644 src/nitro/avatar/animation/IAnimationLayerData.ts create mode 100644 src/nitro/avatar/animation/IAnimationManager.ts create mode 100644 src/nitro/avatar/animation/IAvatarDataContainer.ts create mode 100644 src/nitro/avatar/animation/ISpriteDataContainer.ts create mode 100644 src/nitro/avatar/animation/SpriteDataContainer.ts create mode 100644 src/nitro/avatar/cache/AvatarImageActionCache.ts create mode 100644 src/nitro/avatar/cache/AvatarImageBodyPartCache.ts create mode 100644 src/nitro/avatar/cache/AvatarImageCache.ts create mode 100644 src/nitro/avatar/cache/AvatarImageDirectionCache.ts create mode 100644 src/nitro/avatar/cache/ImageData.ts create mode 100644 src/nitro/avatar/data/HabboAvatarAnimations.json create mode 100644 src/nitro/avatar/data/HabboAvatarGeometry.json create mode 100644 src/nitro/avatar/data/HabboAvatarPartSets.json create mode 100644 src/nitro/avatar/enum/AvatarAction.ts create mode 100644 src/nitro/avatar/enum/AvatarDirectionAngle.ts create mode 100644 src/nitro/avatar/enum/AvatarEditorFigureCategory.ts create mode 100644 src/nitro/avatar/enum/AvatarEditorInstanceId.ts create mode 100644 src/nitro/avatar/enum/AvatarEditorSideCategory.ts create mode 100644 src/nitro/avatar/enum/AvatarFigurePartType.ts create mode 100644 src/nitro/avatar/enum/AvatarGuideStatus.ts create mode 100644 src/nitro/avatar/enum/AvatarScaleType.ts create mode 100644 src/nitro/avatar/enum/AvatarSetType.ts create mode 100644 src/nitro/avatar/enum/GeometryType.ts create mode 100644 src/nitro/avatar/enum/RenderMode.ts create mode 100644 src/nitro/avatar/events/AvatarRenderEffectLibraryEvent.ts create mode 100644 src/nitro/avatar/events/AvatarRenderEvent.ts create mode 100644 src/nitro/avatar/events/AvatarRenderLibraryEvent.ts create mode 100644 src/nitro/avatar/figuredata/FigureData.ts create mode 100644 src/nitro/avatar/figuredata/FigureDataView.ts create mode 100644 src/nitro/avatar/geometry/AvatarModelGeometry.ts create mode 100644 src/nitro/avatar/geometry/AvatarSet.ts create mode 100644 src/nitro/avatar/geometry/GeometryBodyPart.ts create mode 100644 src/nitro/avatar/geometry/GeometryItem.ts create mode 100644 src/nitro/avatar/geometry/Matrix4x4.ts create mode 100644 src/nitro/avatar/geometry/Node3D.ts create mode 100644 src/nitro/avatar/geometry/Vector3D.ts create mode 100644 src/nitro/avatar/pets/PetCustomPart.ts create mode 100644 src/nitro/avatar/pets/PetFigureData.ts create mode 100644 src/nitro/avatar/pets/PetType.ts create mode 100644 src/nitro/avatar/structure/AnimationData.ts create mode 100644 src/nitro/avatar/structure/AvatarCanvas.ts create mode 100644 src/nitro/avatar/structure/AvatarStructureDownload.ts create mode 100644 src/nitro/avatar/structure/FigureSetData.ts create mode 100644 src/nitro/avatar/structure/IFigureSetData.ts create mode 100644 src/nitro/avatar/structure/IStructureData.ts create mode 100644 src/nitro/avatar/structure/PartSetsData.ts create mode 100644 src/nitro/avatar/structure/animation/AnimationAction.ts create mode 100644 src/nitro/avatar/structure/animation/AnimationActionPart.ts create mode 100644 src/nitro/avatar/structure/animation/AnimationFrame.ts create mode 100644 src/nitro/avatar/structure/figure/FigurePart.ts create mode 100644 src/nitro/avatar/structure/figure/FigurePartSet.ts create mode 100644 src/nitro/avatar/structure/figure/IFigurePart.ts create mode 100644 src/nitro/avatar/structure/figure/IFigurePartSet.ts create mode 100644 src/nitro/avatar/structure/figure/IPalette.ts create mode 100644 src/nitro/avatar/structure/figure/IPartColor.ts create mode 100644 src/nitro/avatar/structure/figure/ISetType.ts create mode 100644 src/nitro/avatar/structure/figure/Palette.ts create mode 100644 src/nitro/avatar/structure/figure/PartColor.ts create mode 100644 src/nitro/avatar/structure/figure/SetType.ts create mode 100644 src/nitro/avatar/structure/parts/ActivePartSet.ts create mode 100644 src/nitro/avatar/structure/parts/PartDefinition.ts create mode 100644 src/nitro/communication/INitroCommunicationManager.ts create mode 100644 src/nitro/communication/NitroCommunicationManager.ts create mode 100644 src/nitro/communication/NitroMessages.ts create mode 100644 src/nitro/communication/demo/NitroCommunicationDemo.ts create mode 100644 src/nitro/communication/demo/NitroCommunicationDemoEvent.ts create mode 100644 src/nitro/communication/messages/incoming/IncomingHeader.ts create mode 100644 src/nitro/communication/messages/incoming/availability/AvailabilityStatusMessageEvent.ts create mode 100644 src/nitro/communication/messages/incoming/avatar/ChangeNameUpdateEvent.ts create mode 100644 src/nitro/communication/messages/incoming/catalog/CatalogClubEvent.ts create mode 100644 src/nitro/communication/messages/incoming/catalog/CatalogClubGiftsEvent.ts create mode 100644 src/nitro/communication/messages/incoming/catalog/CatalogGiftConfigurationEvent.ts create mode 100644 src/nitro/communication/messages/incoming/catalog/CatalogGiftUsernameUnavailableEvent.ts create mode 100644 src/nitro/communication/messages/incoming/catalog/CatalogGroupsEvent.ts create mode 100644 src/nitro/communication/messages/incoming/catalog/CatalogModeEvent.ts create mode 100644 src/nitro/communication/messages/incoming/catalog/CatalogPageEvent.ts create mode 100644 src/nitro/communication/messages/incoming/catalog/CatalogPagesEvent.ts create mode 100644 src/nitro/communication/messages/incoming/catalog/CatalogPurchaseEvent.ts create mode 100644 src/nitro/communication/messages/incoming/catalog/CatalogPurchaseFailedEvent.ts create mode 100644 src/nitro/communication/messages/incoming/catalog/CatalogPurchaseUnavailableEvent.ts create mode 100644 src/nitro/communication/messages/incoming/catalog/CatalogRedeemVoucherErrorEvent.ts create mode 100644 src/nitro/communication/messages/incoming/catalog/CatalogRedeemVoucherOkEvent.ts create mode 100644 src/nitro/communication/messages/incoming/catalog/CatalogSearchEvent.ts create mode 100644 src/nitro/communication/messages/incoming/catalog/CatalogSoldOutEvent.ts create mode 100644 src/nitro/communication/messages/incoming/catalog/CatalogUpdatedEvent.ts create mode 100644 src/nitro/communication/messages/incoming/client/ClientPingEvent.ts create mode 100644 src/nitro/communication/messages/incoming/desktop/DesktopViewEvent.ts create mode 100644 src/nitro/communication/messages/incoming/friendlist/AcceptFriendFailureData.ts create mode 100644 src/nitro/communication/messages/incoming/friendlist/AcceptFriendResultEvent.ts create mode 100644 src/nitro/communication/messages/incoming/friendlist/FindFriendsProcessResultEvent.ts create mode 100644 src/nitro/communication/messages/incoming/friendlist/FollowFriendFailedEvent.ts create mode 100644 src/nitro/communication/messages/incoming/friendlist/FriendCategoryData.ts create mode 100644 src/nitro/communication/messages/incoming/friendlist/FriendListFragmentEvent.ts create mode 100644 src/nitro/communication/messages/incoming/friendlist/FriendListUpdateEvent.ts create mode 100644 src/nitro/communication/messages/incoming/friendlist/FriendNotificationEvent.ts create mode 100644 src/nitro/communication/messages/incoming/friendlist/FriendParser.ts create mode 100644 src/nitro/communication/messages/incoming/friendlist/FriendRequestData.ts create mode 100644 src/nitro/communication/messages/incoming/friendlist/FriendRequestsEvent.ts create mode 100644 src/nitro/communication/messages/incoming/friendlist/HabboSearchResultData.ts create mode 100644 src/nitro/communication/messages/incoming/friendlist/HabboSearchResultEvent.ts create mode 100644 src/nitro/communication/messages/incoming/friendlist/InstantMessageErrorEvent.ts create mode 100644 src/nitro/communication/messages/incoming/friendlist/MessageErrorEvent.ts create mode 100644 src/nitro/communication/messages/incoming/friendlist/MessengerInitEvent.ts create mode 100644 src/nitro/communication/messages/incoming/friendlist/MiniMailNewMessageEvent.ts create mode 100644 src/nitro/communication/messages/incoming/friendlist/MiniMailUnreadCountEvent.ts create mode 100644 src/nitro/communication/messages/incoming/friendlist/NewConsoleMessageEvent.ts create mode 100644 src/nitro/communication/messages/incoming/friendlist/NewFriendRequestEvent.ts create mode 100644 src/nitro/communication/messages/incoming/friendlist/RoomInviteErrorEvent.ts create mode 100644 src/nitro/communication/messages/incoming/friendlist/RoomInviteEvent.ts create mode 100644 src/nitro/communication/messages/incoming/game/LoadGameUrlEvent.ts create mode 100644 src/nitro/communication/messages/incoming/generic/GenericErrorEvent.ts create mode 100644 src/nitro/communication/messages/incoming/group/GroupBadgePartsEvent.ts create mode 100644 src/nitro/communication/messages/incoming/group/GroupBuyDataEvent.ts create mode 100644 src/nitro/communication/messages/incoming/group/GroupConfirmMemberRemoveEvent.ts create mode 100644 src/nitro/communication/messages/incoming/group/GroupInformationEvent.ts create mode 100644 src/nitro/communication/messages/incoming/group/GroupMembersEvent.ts create mode 100644 src/nitro/communication/messages/incoming/group/GroupSettingsEvent.ts create mode 100644 src/nitro/communication/messages/incoming/help/CallForHelpResultMessageEvent.ts create mode 100644 src/nitro/communication/messages/incoming/inventory/achievements/Achievement.ts create mode 100644 src/nitro/communication/messages/incoming/inventory/achievements/AchievementEvent.ts create mode 100644 src/nitro/communication/messages/incoming/inventory/achievements/AchievementResolution.ts create mode 100644 src/nitro/communication/messages/incoming/inventory/achievements/AchievementsEvent.ts create mode 100644 src/nitro/communication/messages/incoming/inventory/achievements/AchievementsScoreEvent.ts create mode 100644 src/nitro/communication/messages/incoming/inventory/avatareffect/AvatarEffect.ts create mode 100644 src/nitro/communication/messages/incoming/inventory/avatareffect/AvatarEffectActivatedEvent.ts create mode 100644 src/nitro/communication/messages/incoming/inventory/avatareffect/AvatarEffectAddedEvent.ts create mode 100644 src/nitro/communication/messages/incoming/inventory/avatareffect/AvatarEffectExpiredEvent.ts create mode 100644 src/nitro/communication/messages/incoming/inventory/avatareffect/AvatarEffectSelectedEvent.ts create mode 100644 src/nitro/communication/messages/incoming/inventory/avatareffect/AvatarEffectsEvent.ts create mode 100644 src/nitro/communication/messages/incoming/inventory/badges/BadgesEvent.ts create mode 100644 src/nitro/communication/messages/incoming/inventory/badges/_Str_8120.ts create mode 100644 src/nitro/communication/messages/incoming/inventory/badges/_Str_8179.ts create mode 100644 src/nitro/communication/messages/incoming/inventory/badges/_Str_8980.ts create mode 100644 src/nitro/communication/messages/incoming/inventory/bots/BotAddedToInventoryEvent.ts create mode 100644 src/nitro/communication/messages/incoming/inventory/bots/BotInventoryEvent.ts create mode 100644 src/nitro/communication/messages/incoming/inventory/bots/BotInventoryMessageEvent.ts create mode 100644 src/nitro/communication/messages/incoming/inventory/bots/BotRemovedFromInventoryEvent.ts create mode 100644 src/nitro/communication/messages/incoming/inventory/clothes/FigureSetIdsMessageEvent.ts create mode 100644 src/nitro/communication/messages/incoming/inventory/clothes/_Str_16135.ts create mode 100644 src/nitro/communication/messages/incoming/inventory/clothes/_Str_17532.ts create mode 100644 src/nitro/communication/messages/incoming/inventory/furni/FurnitureListAddOrUpdateEvent.ts create mode 100644 src/nitro/communication/messages/incoming/inventory/furni/FurnitureListEvent.ts create mode 100644 src/nitro/communication/messages/incoming/inventory/furni/FurnitureListInvalidateEvent.ts create mode 100644 src/nitro/communication/messages/incoming/inventory/furni/FurnitureListRemovedEvent.ts create mode 100644 src/nitro/communication/messages/incoming/inventory/furni/FurniturePostItPlacedEvent.ts create mode 100644 src/nitro/communication/messages/incoming/inventory/furni/IFurnitureItemData.ts create mode 100644 src/nitro/communication/messages/incoming/inventory/furni/gifts/FurnitureGiftOpenedEvent.ts create mode 100644 src/nitro/communication/messages/incoming/inventory/pets/PetAddedToInventoryEvent.ts create mode 100644 src/nitro/communication/messages/incoming/inventory/pets/PetInventoryEvent.ts create mode 100644 src/nitro/communication/messages/incoming/inventory/pets/PetRemovedFromInventoryEvent.ts create mode 100644 src/nitro/communication/messages/incoming/inventory/trading/TradingAcceptEvent.ts create mode 100644 src/nitro/communication/messages/incoming/inventory/trading/TradingCloseEvent.ts create mode 100644 src/nitro/communication/messages/incoming/inventory/trading/TradingCompletedEvent.ts create mode 100644 src/nitro/communication/messages/incoming/inventory/trading/TradingConfirmationEvent.ts create mode 100644 src/nitro/communication/messages/incoming/inventory/trading/TradingListItem.ts create mode 100644 src/nitro/communication/messages/incoming/inventory/trading/TradingListItemEvent.ts create mode 100644 src/nitro/communication/messages/incoming/inventory/trading/TradingNotOpenEvent.ts create mode 100644 src/nitro/communication/messages/incoming/inventory/trading/TradingOpenEvent.ts create mode 100644 src/nitro/communication/messages/incoming/inventory/trading/TradingOpenFailedEvent.ts create mode 100644 src/nitro/communication/messages/incoming/inventory/trading/TradingOtherNotAllowedEvent.ts create mode 100644 src/nitro/communication/messages/incoming/inventory/trading/TradingYouAreNotAllowedEvent.ts create mode 100644 src/nitro/communication/messages/incoming/moderation/ModeratorMessageEvent.ts create mode 100644 src/nitro/communication/messages/incoming/modtool/ModtoolCallForHelpTopicsEvent.ts create mode 100644 src/nitro/communication/messages/incoming/modtool/ModtoolMainEvent.ts create mode 100644 src/nitro/communication/messages/incoming/modtool/ModtoolReceivedRoomsUserEvent.ts create mode 100644 src/nitro/communication/messages/incoming/modtool/ModtoolRoomChatlogEvent.ts create mode 100644 src/nitro/communication/messages/incoming/modtool/ModtoolRoomInfoEvent.ts create mode 100644 src/nitro/communication/messages/incoming/modtool/ModtoolUserChatlogEvent.ts create mode 100644 src/nitro/communication/messages/incoming/modtool/ModtoolUserInfoEvent.ts create mode 100644 src/nitro/communication/messages/incoming/navigator/NavigatorCategoriesEvent.ts create mode 100644 src/nitro/communication/messages/incoming/navigator/NavigatorCollapsedEvent.ts create mode 100644 src/nitro/communication/messages/incoming/navigator/NavigatorEventCategoriesEvent.ts create mode 100644 src/nitro/communication/messages/incoming/navigator/NavigatorHomeRoomEvent.ts create mode 100644 src/nitro/communication/messages/incoming/navigator/NavigatorLiftedEvent.ts create mode 100644 src/nitro/communication/messages/incoming/navigator/NavigatorMetadataEvent.ts create mode 100644 src/nitro/communication/messages/incoming/navigator/NavigatorOpenRoomCreatorEvent.ts create mode 100644 src/nitro/communication/messages/incoming/navigator/NavigatorSearchEvent.ts create mode 100644 src/nitro/communication/messages/incoming/navigator/NavigatorSearchesEvent.ts create mode 100644 src/nitro/communication/messages/incoming/navigator/NavigatorSettingsEvent.ts create mode 100644 src/nitro/communication/messages/incoming/notifications/BotErrorEvent.ts create mode 100644 src/nitro/communication/messages/incoming/notifications/HabboBroadcastMessageEvent.ts create mode 100644 src/nitro/communication/messages/incoming/notifications/HotelWillShutdownEvent.ts create mode 100644 src/nitro/communication/messages/incoming/notifications/MOTDNotificationEvent.ts create mode 100644 src/nitro/communication/messages/incoming/notifications/NotificationDialogMessageEvent.ts create mode 100644 src/nitro/communication/messages/incoming/notifications/PetPlacingErrorEvent.ts create mode 100644 src/nitro/communication/messages/incoming/notifications/RespectReceivedEvent.ts create mode 100644 src/nitro/communication/messages/incoming/notifications/UnseenItemsEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/access/RoomEnterErrorEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/access/RoomEnterEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/access/RoomForwardEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/access/doorbell/RoomDoorbellAcceptedEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/access/doorbell/RoomDoorbellEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/access/doorbell/RoomDoorbellRejectedEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/access/rights/RoomRightsClearEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/access/rights/RoomRightsEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/access/rights/RoomRightsOwnerEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/bots/BotCommandConfigurationEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/data/RoomBannedUsersEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/data/RoomChatSettingsEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/data/RoomInfoEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/data/RoomInfoOwnerEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/data/RoomScoreEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/data/RoomSettingsErrorEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/data/RoomSettingsEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/data/RoomSettingsSavedEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/data/RoomSettingsUpdatedEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/data/RoomUsersWithRightsEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/engine/ObjectsRollingEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/engine/RoomCreatedEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/furniture/FurnitureAliasesEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/furniture/FurnitureDataEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/furniture/FurnitureItemDataEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/furniture/FurnitureStackHeightEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/furniture/FurnitureState2Event.ts create mode 100644 src/nitro/communication/messages/incoming/room/furniture/FurnitureStateEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/furniture/LoveLockFurniFinishedEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/furniture/LoveLockFurniFriendConfirmedEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/furniture/LoveLockFurniStartEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/furniture/RoomDimmerPresetsMessageEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/furniture/floor/FurnitureFloorAddEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/furniture/floor/FurnitureFloorEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/furniture/floor/FurnitureFloorRemoveEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/furniture/floor/FurnitureFloorUpdateEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/furniture/moodlightFromServer.ts create mode 100644 src/nitro/communication/messages/incoming/room/furniture/wall/FurnitureWallAddEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/furniture/wall/FurnitureWallEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/furniture/wall/FurnitureWallRemoveEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/furniture/wall/FurnitureWallUpdateEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/mapping/RoomDoorEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/mapping/RoomHeightMapEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/mapping/RoomHeightMapUpdateEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/mapping/RoomModelEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/mapping/RoomModelNameEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/mapping/RoomPaintEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/mapping/RoomThicknessEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/pet/PetFigureUpdateEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/pet/PetInfoEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/pet/_Str_3763.ts create mode 100644 src/nitro/communication/messages/incoming/room/pet/_Str_5753.ts create mode 100644 src/nitro/communication/messages/incoming/room/session/YouArePlayingGameEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/unit/RoomUnitDanceEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/unit/RoomUnitEffectEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/unit/RoomUnitEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/unit/RoomUnitExpressionEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/unit/RoomUnitHandItemEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/unit/RoomUnitHandItemReceivedEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/unit/RoomUnitIdleEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/unit/RoomUnitInfoEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/unit/RoomUnitNumberEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/unit/RoomUnitRemoveEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/unit/RoomUnitStatusEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/unit/chat/FloodControlEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/unit/chat/RemainingMuteEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/unit/chat/RoomUnitChatEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/unit/chat/RoomUnitChatShoutEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/unit/chat/RoomUnitChatWhisperEvent.ts create mode 100644 src/nitro/communication/messages/incoming/room/unit/chat/RoomUnitTypingEvent.ts create mode 100644 src/nitro/communication/messages/incoming/roomevents/ActionDefinition.ts create mode 100644 src/nitro/communication/messages/incoming/roomevents/ConditionDefinition.ts create mode 100644 src/nitro/communication/messages/incoming/roomevents/RoomMutedEvent.ts create mode 100644 src/nitro/communication/messages/incoming/roomevents/TriggerDefinition.ts create mode 100644 src/nitro/communication/messages/incoming/roomevents/Triggerable.ts create mode 100644 src/nitro/communication/messages/incoming/roomevents/WiredFurniActionEvent.ts create mode 100644 src/nitro/communication/messages/incoming/roomevents/WiredFurniConditionEvent.ts create mode 100644 src/nitro/communication/messages/incoming/roomevents/WiredFurniTriggerEvent.ts create mode 100644 src/nitro/communication/messages/incoming/roomevents/WiredOpenEvent.ts create mode 100644 src/nitro/communication/messages/incoming/roomevents/WiredRewardResultMessageEvent.ts create mode 100644 src/nitro/communication/messages/incoming/roomevents/WiredSaveSuccessEvent.ts create mode 100644 src/nitro/communication/messages/incoming/roomevents/WiredValidationErrorEvent.ts create mode 100644 src/nitro/communication/messages/incoming/security/AuthenticatedEvent.ts create mode 100644 src/nitro/communication/messages/incoming/user/IgnoreResultEvent.ts create mode 100644 src/nitro/communication/messages/incoming/user/IgnoredUsersEvent.ts create mode 100644 src/nitro/communication/messages/incoming/user/InClientLinkEvent.ts create mode 100644 src/nitro/communication/messages/incoming/user/access/UserPerksEvent.ts create mode 100644 src/nitro/communication/messages/incoming/user/access/UserPermissionsEvent.ts create mode 100644 src/nitro/communication/messages/incoming/user/data/UserCurrentBadgesEvent.ts create mode 100644 src/nitro/communication/messages/incoming/user/data/UserFigureEvent.ts create mode 100644 src/nitro/communication/messages/incoming/user/data/UserInfoEvent.ts create mode 100644 src/nitro/communication/messages/incoming/user/data/UserNameChangeMessageEvent.ts create mode 100644 src/nitro/communication/messages/incoming/user/data/UserProfileEvent.ts create mode 100644 src/nitro/communication/messages/incoming/user/data/UserRelationshipsEvent.ts create mode 100644 src/nitro/communication/messages/incoming/user/data/UserSettingsEvent.ts create mode 100644 src/nitro/communication/messages/incoming/user/inventory/currency/UserCreditsEvent.ts create mode 100644 src/nitro/communication/messages/incoming/user/inventory/currency/UserCurrencyEvent.ts create mode 100644 src/nitro/communication/messages/incoming/user/inventory/currency/UserCurrencyUpdateEvent.ts create mode 100644 src/nitro/communication/messages/incoming/user/inventory/subscription/UserSubscriptionEvent.ts create mode 100644 src/nitro/communication/messages/incoming/user/wardrobe/UserWardrobePageEvent.ts create mode 100644 src/nitro/communication/messages/outgoing/OutgoingHeader.ts create mode 100644 src/nitro/communication/messages/outgoing/achievements/RequestAchievementsMessageComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/catalog/CatalogGroupsComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/catalog/CatalogModeComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/catalog/CatalogPageComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/catalog/CatalogPurchaseComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/catalog/CatalogPurchaseGiftComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/catalog/CatalogRequestGiftConfigurationComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/catalog/CatalogRequestVipGiftsComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/catalog/CatalogRequestVipOffersComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/catalog/CatalogSearchComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/catalog/CatalogSelectClubGiftComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/catalog/RedeemItemClothingComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/catalog/RedeemVoucherComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/client/ClientPongComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/client/ClientReleaseVersionComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/desktop/DesktopViewComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/friendlist/AcceptFriendComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/friendlist/DeclineFriendComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/friendlist/FindNewFriendsComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/friendlist/FollowFriendComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/friendlist/FriendListUpdateComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/friendlist/GetFriendRequestsComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/friendlist/HabboSearchComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/friendlist/MessengerInitComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/friendlist/RemoveFriendComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/friendlist/RequestFriendComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/friendlist/SendMessageComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/friendlist/SendRoomInviteComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/friendlist/SetRelationshipStatusComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/friendlist/VisitUserComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/group/GroupAdminGiveComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/group/GroupAdminTakeComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/group/GroupBadgePartsComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/group/GroupBuyComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/group/GroupBuyDataComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/group/GroupConfirmRemoveMemberComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/group/GroupDeleteComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/group/GroupInformationComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/group/GroupJoinComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/group/GroupMembersComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/group/GroupMembershipAcceptComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/group/GroupMembershipDeclineComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/group/GroupRemoveMemberComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/group/GroupSaveBadgeComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/group/GroupSaveColorsComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/group/GroupSaveInformationComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/group/GroupSavePreferencesComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/group/GroupSettingsComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/handshake/InfoRetrieveBaseMessageComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/handshake/SecurityTicketComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/inventory/badges/RequestBadgesComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/inventory/badges/SetActivatedBadgesComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/inventory/bots/GetBotInventoryComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/inventory/furni/FurnitureList2Composer.ts create mode 100644 src/nitro/communication/messages/outgoing/inventory/furni/FurnitureListComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/inventory/pets/RequestPetsComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/inventory/trading/TradingAcceptComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/inventory/trading/TradingCancelComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/inventory/trading/TradingCloseComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/inventory/trading/TradingConfirmationComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/inventory/trading/TradingListAddItemComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/inventory/trading/TradingListAddItemsComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/inventory/trading/TradingListRemoveItemComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/inventory/trading/TradingOpenComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/inventory/trading/TradingUnacceptComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/modtool/ModtoolChangeRoomSettingsComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/modtool/ModtoolEventAlertComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/modtool/ModtoolRequestRoomChatlogComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/modtool/ModtoolRequestRoomInfoComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/modtool/ModtoolRequestUserChatlogComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/modtool/ModtoolRequestUserInfoComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/modtool/ModtoolRequestUserRoomsComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/modtool/ModtoolRoomAlertComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/modtool/ModtoolSanctionAlertComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/modtool/ModtoolSanctionBanComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/modtool/ModtoolSanctionKickComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/modtool/ModtoolSanctionMuteComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/modtool/ModtoolSanctionTradelockComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/navigator/ConvertGlobalRoomIdComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/navigator/NavigatorCategoriesComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/navigator/NavigatorCategoryListModeComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/navigator/NavigatorInitComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/navigator/NavigatorSearchCloseComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/navigator/NavigatorSearchComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/navigator/NavigatorSearchOpenComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/navigator/NavigatorSearchSaveComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/navigator/NavigatorSettingsComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/navigator/NavigatorSettingsSaveComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/pet/PetRespectComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/pet/RequestPetInfoComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/RoomCreateComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/access/RoomDoorbellAccessComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/access/RoomEnterComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/action/RoomAmbassadorAlertComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/action/RoomBanUserComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/action/RoomDeleteComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/action/RoomGiveRightsComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/action/RoomKickUserComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/action/RoomLikeRoomComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/action/RoomMuteUserComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/action/RoomStaffPickComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/action/RoomTakeRightsComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/action/RoomUnbanUserComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/bots/RequestBotConfigurationComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/data/RoomBannedUsersComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/data/RoomInfoComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/data/RoomSettingsComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/data/RoomUsersWithRightsComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/data/SaveRoomSettingsComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/engine/BotPlaceComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/engine/BotRemoveComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/engine/BotSkillSaveComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/engine/GetItemDataComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/engine/ModifyWallItemDataComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/engine/PetMoveComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/engine/PetPlaceComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/engine/PetRemoveComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/engine/RemoveWallItemComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/furniture/FurnitureAliasesComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/furniture/FurniturePickupComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/furniture/FurniturePlaceComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/furniture/FurniturePlacePaintComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/furniture/FurniturePostItPlaceComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/furniture/ads/RoomAdsUpdateComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/furniture/dimmer/MoodlightSettingsComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/furniture/dimmer/MoodlightSettingsSaveComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/furniture/dimmer/MoodlightTogggleStateComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/furniture/floor/FurnitureFloorUpdateComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/furniture/logic/FurnitureColorWheelComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/furniture/logic/FurnitureDiceActivateComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/furniture/logic/FurnitureDiceDeactivateComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/furniture/logic/FurnitureExchangeComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/furniture/logic/FurnitureMultiStateComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/furniture/logic/FurnitureOneWayDoorComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/furniture/logic/FurnitureRandomStateComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/furniture/logic/FurnitureStackHeightComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/furniture/logic/FurnitureWallMultiStateComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/furniture/logic/LoveLockStartConfirmComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/furniture/mannequin/FurnitureMannequinSaveLookComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/furniture/mannequin/FurnitureMannequinSaveNameComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/furniture/presents/OpenPresentComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/furniture/toner/ApplyTonerComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/furniture/wall/FurnitureWallUpdateComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/mapping/RoomModelComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/unit/RoomUnitActionComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/unit/RoomUnitDanceComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/unit/RoomUnitDropHandItemComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/unit/RoomUnitGiveHandItemComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/unit/RoomUnitLookComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/unit/RoomUnitPostureComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/unit/RoomUnitSignComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/unit/RoomUnitWalkComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/unit/chat/RoomUnitChatComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/unit/chat/RoomUnitChatShoutComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/unit/chat/RoomUnitChatStyleComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/unit/chat/RoomUnitChatWhisperComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/unit/chat/RoomUnitTypingStartComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/room/unit/chat/RoomUnitTypingStopComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/roomevents/ApplySnapshotMessageComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/roomevents/OpenMessageComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/roomevents/RoomMuteComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/roomevents/UpdateActionMessageComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/roomevents/UpdateConditionMessageComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/roomevents/UpdateTriggerMessageComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/user/UserRespectComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/user/data/GetIgnoredUsersComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/user/data/IgnoreUserComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/user/data/IgnoreUserIdComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/user/data/UnignoreUserComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/user/data/UserCurrentBadgesComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/user/data/UserFigureComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/user/data/UserHomeRoomComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/user/data/UserMottoComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/user/data/UserProfileComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/user/data/UserRelationshipsComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/user/inventory/currency/UserCurrencyComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/user/inventory/subscription/UserSubscriptionComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/user/settings/UserSettingsCameraFollowComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/user/settings/UserSettingsOldChatComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/user/settings/UserSettingsRoomInvitesComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/user/settings/UserSettingsSoundComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/user/wardrobe/UserWardrobePageComposer.ts create mode 100644 src/nitro/communication/messages/outgoing/user/wardrobe/UserWardrobeSaveComposer.ts create mode 100644 src/nitro/communication/messages/parser/availability/AvailabilityStatusMessageParser.ts create mode 100644 src/nitro/communication/messages/parser/avatar/ChangeNameUpdateParser.ts create mode 100644 src/nitro/communication/messages/parser/catalog/CatalogClubGiftsParser.ts create mode 100644 src/nitro/communication/messages/parser/catalog/CatalogClubParser.ts create mode 100644 src/nitro/communication/messages/parser/catalog/CatalogGiftConfigurationParser.ts create mode 100644 src/nitro/communication/messages/parser/catalog/CatalogGiftUsernameUnavailableParser.ts create mode 100644 src/nitro/communication/messages/parser/catalog/CatalogGroupsParser.ts create mode 100644 src/nitro/communication/messages/parser/catalog/CatalogModeParser.ts create mode 100644 src/nitro/communication/messages/parser/catalog/CatalogPageParser.ts create mode 100644 src/nitro/communication/messages/parser/catalog/CatalogPagesParser.ts create mode 100644 src/nitro/communication/messages/parser/catalog/CatalogPurchaseFailedParser.ts create mode 100644 src/nitro/communication/messages/parser/catalog/CatalogPurchaseParser.ts create mode 100644 src/nitro/communication/messages/parser/catalog/CatalogPurchaseUnavailableParser.ts create mode 100644 src/nitro/communication/messages/parser/catalog/CatalogRedeemVoucherErrorParser.ts create mode 100644 src/nitro/communication/messages/parser/catalog/CatalogRedeemVoucherOkParser.ts create mode 100644 src/nitro/communication/messages/parser/catalog/CatalogSearchParser.ts create mode 100644 src/nitro/communication/messages/parser/catalog/CatalogSoldOutParser.ts create mode 100644 src/nitro/communication/messages/parser/catalog/CatalogUpdatedParser.ts create mode 100644 src/nitro/communication/messages/parser/catalog/utils/CatalogClubOfferData.ts create mode 100644 src/nitro/communication/messages/parser/catalog/utils/CatalogFrontPageItem.ts create mode 100644 src/nitro/communication/messages/parser/catalog/utils/CatalogGroupData.ts create mode 100644 src/nitro/communication/messages/parser/catalog/utils/CatalogLocalizationData.ts create mode 100644 src/nitro/communication/messages/parser/catalog/utils/CatalogPageData.ts create mode 100644 src/nitro/communication/messages/parser/catalog/utils/CatalogPageOfferData.ts create mode 100644 src/nitro/communication/messages/parser/catalog/utils/CatalogProductOfferData.ts create mode 100644 src/nitro/communication/messages/parser/catalog/utils/CatalogPurchaseData.ts create mode 100644 src/nitro/communication/messages/parser/catalog/utils/CatalogSearchData.ts create mode 100644 src/nitro/communication/messages/parser/catalog/utils/ICatalogLocalizationData.ts create mode 100644 src/nitro/communication/messages/parser/catalog/utils/ICatalogPageData.ts create mode 100644 src/nitro/communication/messages/parser/catalog/utils/ICatalogPageParser.ts create mode 100644 src/nitro/communication/messages/parser/catalog/utils/_Str_5178.ts create mode 100644 src/nitro/communication/messages/parser/client/ClientPingParser.ts create mode 100644 src/nitro/communication/messages/parser/desktop/DesktopViewParser.ts create mode 100644 src/nitro/communication/messages/parser/friendlist/AcceptFriendResultParser.ts create mode 100644 src/nitro/communication/messages/parser/friendlist/FindFriendsProcessResultParser.ts create mode 100644 src/nitro/communication/messages/parser/friendlist/FollowFriendFailedParser.ts create mode 100644 src/nitro/communication/messages/parser/friendlist/FriendListFragmentMessageParser.ts create mode 100644 src/nitro/communication/messages/parser/friendlist/FriendListUpdateParser.ts create mode 100644 src/nitro/communication/messages/parser/friendlist/FriendNotificationParser.ts create mode 100644 src/nitro/communication/messages/parser/friendlist/FriendRequestsParser.ts create mode 100644 src/nitro/communication/messages/parser/friendlist/HabboSearchResultParser.ts create mode 100644 src/nitro/communication/messages/parser/friendlist/InstantMessageErrorParser.ts create mode 100644 src/nitro/communication/messages/parser/friendlist/MessageErrorParser.ts create mode 100644 src/nitro/communication/messages/parser/friendlist/MessengerInitParser.ts create mode 100644 src/nitro/communication/messages/parser/friendlist/MiniMailNewMessageParser.ts create mode 100644 src/nitro/communication/messages/parser/friendlist/MiniMailUnreadCountParser.ts create mode 100644 src/nitro/communication/messages/parser/friendlist/NewConsoleMessageParser.ts create mode 100644 src/nitro/communication/messages/parser/friendlist/NewFriendRequestMessageParser.ts create mode 100644 src/nitro/communication/messages/parser/friendlist/RoomInviteErrorParser.ts create mode 100644 src/nitro/communication/messages/parser/friendlist/RoomInviteMessageParser.ts create mode 100644 src/nitro/communication/messages/parser/game/LoadGameUrlParser.ts create mode 100644 src/nitro/communication/messages/parser/generic/GenericErrorParser.ts create mode 100644 src/nitro/communication/messages/parser/group/GroupBadgePartsParser.ts create mode 100644 src/nitro/communication/messages/parser/group/GroupBuyDataParser.ts create mode 100644 src/nitro/communication/messages/parser/group/GroupConfirmMemberRemoveParser.ts create mode 100644 src/nitro/communication/messages/parser/group/GroupInformationParser.ts create mode 100644 src/nitro/communication/messages/parser/group/GroupMembersParser.ts create mode 100644 src/nitro/communication/messages/parser/group/GroupSettingsParser.ts create mode 100644 src/nitro/communication/messages/parser/group/utils/GroupBadgePart.ts create mode 100644 src/nitro/communication/messages/parser/group/utils/GroupDataParser.ts create mode 100644 src/nitro/communication/messages/parser/group/utils/GroupMemberParser.ts create mode 100644 src/nitro/communication/messages/parser/help/CallForHelpResultMessageParser.ts create mode 100644 src/nitro/communication/messages/parser/inventory/achievements/AchievementParser.ts create mode 100644 src/nitro/communication/messages/parser/inventory/achievements/AchievementsParser.ts create mode 100644 src/nitro/communication/messages/parser/inventory/achievements/AchievementsScoreParser.ts create mode 100644 src/nitro/communication/messages/parser/inventory/avatareffect/AvatarEffectActivatedParser.ts create mode 100644 src/nitro/communication/messages/parser/inventory/avatareffect/AvatarEffectAddedParser.ts create mode 100644 src/nitro/communication/messages/parser/inventory/avatareffect/AvatarEffectExpiredParser.ts create mode 100644 src/nitro/communication/messages/parser/inventory/avatareffect/AvatarEffectSelectedParser.ts create mode 100644 src/nitro/communication/messages/parser/inventory/avatareffect/AvatarEffectsParser.ts create mode 100644 src/nitro/communication/messages/parser/inventory/badges/BadgesParser.ts create mode 100644 src/nitro/communication/messages/parser/inventory/badges/_Str_7305.ts create mode 100644 src/nitro/communication/messages/parser/inventory/badges/_Str_7446.ts create mode 100644 src/nitro/communication/messages/parser/inventory/badges/_Str_7491.ts create mode 100644 src/nitro/communication/messages/parser/inventory/badges/_Str_9135.ts create mode 100644 src/nitro/communication/messages/parser/inventory/bots/BotAddedToInventoryParser.ts create mode 100644 src/nitro/communication/messages/parser/inventory/bots/BotData.ts create mode 100644 src/nitro/communication/messages/parser/inventory/bots/BotInventoryMessageParser.ts create mode 100644 src/nitro/communication/messages/parser/inventory/bots/BotReceivedMessageParser.ts create mode 100644 src/nitro/communication/messages/parser/inventory/bots/BotRemovedFromInventoryParser.ts create mode 100644 src/nitro/communication/messages/parser/inventory/clothing/FigureSetIdsMessageParser.ts create mode 100644 src/nitro/communication/messages/parser/inventory/clothing/_Str_8728.ts create mode 100644 src/nitro/communication/messages/parser/inventory/clothing/_Str_9021.ts create mode 100644 src/nitro/communication/messages/parser/inventory/furniture/FurnitureGiftOpenedParser.ts create mode 100644 src/nitro/communication/messages/parser/inventory/furniture/FurnitureListAddOrUpdateParser.ts create mode 100644 src/nitro/communication/messages/parser/inventory/furniture/FurnitureListInvalidateParser.ts create mode 100644 src/nitro/communication/messages/parser/inventory/furniture/FurnitureListParser.ts create mode 100644 src/nitro/communication/messages/parser/inventory/furniture/FurnitureListRemovedParser.ts create mode 100644 src/nitro/communication/messages/parser/inventory/furniture/FurniturePostItPlacedParser.ts create mode 100644 src/nitro/communication/messages/parser/inventory/furniture/utils/FurnitureListItemParser.ts create mode 100644 src/nitro/communication/messages/parser/inventory/pets/PetAddedToInventoryParser.ts create mode 100644 src/nitro/communication/messages/parser/inventory/pets/PetBoughtNotificationMessageParser.ts create mode 100644 src/nitro/communication/messages/parser/inventory/pets/PetData.ts create mode 100644 src/nitro/communication/messages/parser/inventory/pets/PetFigureData.ts create mode 100644 src/nitro/communication/messages/parser/inventory/pets/PetInventoryParser.ts create mode 100644 src/nitro/communication/messages/parser/inventory/pets/PetRemovedFromInventoryParser.ts create mode 100644 src/nitro/communication/messages/parser/inventory/pets/_Str_6256.ts create mode 100644 src/nitro/communication/messages/parser/inventory/pets/_Str_6719.ts create mode 100644 src/nitro/communication/messages/parser/inventory/pets/_Str_7486.ts create mode 100644 src/nitro/communication/messages/parser/inventory/pets/_Str_7523.ts create mode 100644 src/nitro/communication/messages/parser/inventory/pets/_Str_9220.ts create mode 100644 src/nitro/communication/messages/parser/inventory/purse/UserCreditsMessageParser.ts create mode 100644 src/nitro/communication/messages/parser/inventory/trading/TradingAcceptParser.ts create mode 100644 src/nitro/communication/messages/parser/inventory/trading/TradingCloseParser.ts create mode 100644 src/nitro/communication/messages/parser/inventory/trading/TradingCompletedParser.ts create mode 100644 src/nitro/communication/messages/parser/inventory/trading/TradingConfirmationParser.ts create mode 100644 src/nitro/communication/messages/parser/inventory/trading/TradingListItemParser.ts create mode 100644 src/nitro/communication/messages/parser/inventory/trading/TradingNotOpenParser.ts create mode 100644 src/nitro/communication/messages/parser/inventory/trading/TradingOpenFailedParser.ts create mode 100644 src/nitro/communication/messages/parser/inventory/trading/TradingOpenParser.ts create mode 100644 src/nitro/communication/messages/parser/inventory/trading/TradingOtherNotAllowedParser.ts create mode 100644 src/nitro/communication/messages/parser/inventory/trading/TradingYouAreNotAllowedParser.ts create mode 100644 src/nitro/communication/messages/parser/moderation/ModeratorMessageParser.ts create mode 100644 src/nitro/communication/messages/parser/modtool/ModtoolCFHTopicsParser.ts create mode 100644 src/nitro/communication/messages/parser/modtool/ModtoolMainParser.ts create mode 100644 src/nitro/communication/messages/parser/modtool/ModtoolRoomChatlogParser.ts create mode 100644 src/nitro/communication/messages/parser/modtool/ModtoolRoomInfoParser.ts create mode 100644 src/nitro/communication/messages/parser/modtool/ModtoolRoomUsersParser.ts create mode 100644 src/nitro/communication/messages/parser/modtool/ModtoolUserChatlogParser.ts create mode 100644 src/nitro/communication/messages/parser/modtool/ModtoolUserInfoParser.ts create mode 100644 src/nitro/communication/messages/parser/modtool/utils/CallForHelpCategoryData.ts create mode 100644 src/nitro/communication/messages/parser/modtool/utils/IChatlog.ts create mode 100644 src/nitro/communication/messages/parser/modtool/utils/ModtoolRoomChatlogLine.ts create mode 100644 src/nitro/communication/messages/parser/modtool/utils/ModtoolRoomVisitedData.ts create mode 100644 src/nitro/communication/messages/parser/modtool/utils/ModtoolUserChatlogParserChatlog.ts create mode 100644 src/nitro/communication/messages/parser/modtool/utils/ModtoolUserChatlogParserVisit.ts create mode 100644 src/nitro/communication/messages/parser/modtool/utils/ModtoolUserVisitedRoomsRoom.ts create mode 100644 src/nitro/communication/messages/parser/modtool/utils/_Str_2484.ts create mode 100644 src/nitro/communication/messages/parser/modtool/utils/_Str_5018.ts create mode 100644 src/nitro/communication/messages/parser/modtool/utils/_Str_5460.ts create mode 100644 src/nitro/communication/messages/parser/modtool/utils/_Str_5467.ts create mode 100644 src/nitro/communication/messages/parser/modtool/utils/_Str_8176.ts create mode 100644 src/nitro/communication/messages/parser/navigator/NavigatorCategoriesParser.ts create mode 100644 src/nitro/communication/messages/parser/navigator/NavigatorCategoryDataParser.ts create mode 100644 src/nitro/communication/messages/parser/navigator/NavigatorCollapsedParser.ts create mode 100644 src/nitro/communication/messages/parser/navigator/NavigatorEventCategoriesParser.ts create mode 100644 src/nitro/communication/messages/parser/navigator/NavigatorEventCategoryDataParser.ts create mode 100644 src/nitro/communication/messages/parser/navigator/NavigatorHomeRoomParser.ts create mode 100644 src/nitro/communication/messages/parser/navigator/NavigatorLiftedDataParser.ts create mode 100644 src/nitro/communication/messages/parser/navigator/NavigatorLiftedParser.ts create mode 100644 src/nitro/communication/messages/parser/navigator/NavigatorMetadataParser.ts create mode 100644 src/nitro/communication/messages/parser/navigator/NavigatorOpenRoomCreatorParser.ts create mode 100644 src/nitro/communication/messages/parser/navigator/NavigatorSearchParser.ts create mode 100644 src/nitro/communication/messages/parser/navigator/NavigatorSearchesParser.ts create mode 100644 src/nitro/communication/messages/parser/navigator/NavigatorSettingsParser.ts create mode 100644 src/nitro/communication/messages/parser/navigator/utils/NavigatorSavedSearch.ts create mode 100644 src/nitro/communication/messages/parser/navigator/utils/NavigatorSearchResultList.ts create mode 100644 src/nitro/communication/messages/parser/navigator/utils/NavigatorSearchResultSet.ts create mode 100644 src/nitro/communication/messages/parser/navigator/utils/NavigatorTopLevelContext.ts create mode 100644 src/nitro/communication/messages/parser/notifications/BotErrorEventParser.ts create mode 100644 src/nitro/communication/messages/parser/notifications/HabboBroadcastMessageParser.ts create mode 100644 src/nitro/communication/messages/parser/notifications/HotelWillShutdownParser.ts create mode 100644 src/nitro/communication/messages/parser/notifications/MOTDNotificationParser.ts create mode 100644 src/nitro/communication/messages/parser/notifications/NotificationDialogMessageParser.ts create mode 100644 src/nitro/communication/messages/parser/notifications/PetPlacingErrorEventParser.ts create mode 100644 src/nitro/communication/messages/parser/notifications/RespectReceivedParser.ts create mode 100644 src/nitro/communication/messages/parser/notifications/UnseenItemsParser.ts create mode 100644 src/nitro/communication/messages/parser/room/access/RoomEnterErrorParser.ts create mode 100644 src/nitro/communication/messages/parser/room/access/RoomEnterParser.ts create mode 100644 src/nitro/communication/messages/parser/room/access/RoomFowardParser.ts create mode 100644 src/nitro/communication/messages/parser/room/access/doorbell/RoomDoorbellAcceptedParser.ts create mode 100644 src/nitro/communication/messages/parser/room/access/doorbell/RoomDoorbellParser.ts create mode 100644 src/nitro/communication/messages/parser/room/access/doorbell/RoomDoorbellRejectedParser.ts create mode 100644 src/nitro/communication/messages/parser/room/access/rights/RoomRightsClearParser.ts create mode 100644 src/nitro/communication/messages/parser/room/access/rights/RoomRightsOwnerParser.ts create mode 100644 src/nitro/communication/messages/parser/room/access/rights/RoomRightsParser.ts create mode 100644 src/nitro/communication/messages/parser/room/bots/BotCommandConfigurationParser.ts create mode 100644 src/nitro/communication/messages/parser/room/data/RoomChatParser.ts create mode 100644 src/nitro/communication/messages/parser/room/data/RoomChatSettingsParser.ts create mode 100644 src/nitro/communication/messages/parser/room/data/RoomDataParser.ts create mode 100644 src/nitro/communication/messages/parser/room/data/RoomInfoOwnerParser.ts create mode 100644 src/nitro/communication/messages/parser/room/data/RoomInfoParser.ts create mode 100644 src/nitro/communication/messages/parser/room/data/RoomModerationParser.ts create mode 100644 src/nitro/communication/messages/parser/room/data/RoomScoreParser.ts create mode 100644 src/nitro/communication/messages/parser/room/data/RoomSettingsErrorParser.ts create mode 100644 src/nitro/communication/messages/parser/room/data/RoomSettingsParser.ts create mode 100644 src/nitro/communication/messages/parser/room/data/RoomSettingsSavedParser.ts create mode 100644 src/nitro/communication/messages/parser/room/data/RoomSettingsUpdatedParser.ts create mode 100644 src/nitro/communication/messages/parser/room/data/RoomSettingsUsersListParser.ts create mode 100644 src/nitro/communication/messages/parser/room/engine/ObjectsRollingParser.ts create mode 100644 src/nitro/communication/messages/parser/room/engine/RoomCreatedParser.ts create mode 100644 src/nitro/communication/messages/parser/room/furniture/FurnitureAliasesParser.ts create mode 100644 src/nitro/communication/messages/parser/room/furniture/FurnitureDataParser.ts create mode 100644 src/nitro/communication/messages/parser/room/furniture/FurnitureItemDataParser.ts create mode 100644 src/nitro/communication/messages/parser/room/furniture/FurnitureStackHeightParser.ts create mode 100644 src/nitro/communication/messages/parser/room/furniture/FurnitureState2Parser.ts create mode 100644 src/nitro/communication/messages/parser/room/furniture/FurnitureStateParser.ts create mode 100644 src/nitro/communication/messages/parser/room/furniture/LoveLockFurniFinishedParser.ts create mode 100644 src/nitro/communication/messages/parser/room/furniture/LoveLockFurniFriendConfirmedParser.ts create mode 100644 src/nitro/communication/messages/parser/room/furniture/LoveLockFurniStartParser.ts create mode 100644 src/nitro/communication/messages/parser/room/furniture/RoomDimmerPresetsMessageParser.ts create mode 100644 src/nitro/communication/messages/parser/room/furniture/floor/FurnitureFloorAddParser.ts create mode 100644 src/nitro/communication/messages/parser/room/furniture/floor/FurnitureFloorDataParser.ts create mode 100644 src/nitro/communication/messages/parser/room/furniture/floor/FurnitureFloorParser.ts create mode 100644 src/nitro/communication/messages/parser/room/furniture/floor/FurnitureFloorRemoveParser.ts create mode 100644 src/nitro/communication/messages/parser/room/furniture/floor/FurnitureFloorUpdateParser.ts create mode 100644 src/nitro/communication/messages/parser/room/furniture/wall/FurnitureWallAddParser.ts create mode 100644 src/nitro/communication/messages/parser/room/furniture/wall/FurnitureWallDataParser.ts create mode 100644 src/nitro/communication/messages/parser/room/furniture/wall/FurnitureWallParser.ts create mode 100644 src/nitro/communication/messages/parser/room/furniture/wall/FurnitureWallRemoveParser.ts create mode 100644 src/nitro/communication/messages/parser/room/furniture/wall/FurnitureWallUpdateParser.ts create mode 100644 src/nitro/communication/messages/parser/room/mapping/RoomDoorParser.ts create mode 100644 src/nitro/communication/messages/parser/room/mapping/RoomHeightMapParser.ts create mode 100644 src/nitro/communication/messages/parser/room/mapping/RoomHeightMapUpdateParser.ts create mode 100644 src/nitro/communication/messages/parser/room/mapping/RoomModelNameParser.ts create mode 100644 src/nitro/communication/messages/parser/room/mapping/RoomModelParser.ts create mode 100644 src/nitro/communication/messages/parser/room/mapping/RoomPaintParser.ts create mode 100644 src/nitro/communication/messages/parser/room/mapping/RoomThicknessParser.ts create mode 100644 src/nitro/communication/messages/parser/room/pet/PetFigureUpdateParser.ts create mode 100644 src/nitro/communication/messages/parser/room/pet/PetInfoParser.ts create mode 100644 src/nitro/communication/messages/parser/room/session/YouArePlayingGameParser.ts create mode 100644 src/nitro/communication/messages/parser/room/unit/RoomUnitDanceParser.ts create mode 100644 src/nitro/communication/messages/parser/room/unit/RoomUnitEffectParser.ts create mode 100644 src/nitro/communication/messages/parser/room/unit/RoomUnitExpressionParser.ts create mode 100644 src/nitro/communication/messages/parser/room/unit/RoomUnitHandItemParser.ts create mode 100644 src/nitro/communication/messages/parser/room/unit/RoomUnitHandItemReceivedParser.ts create mode 100644 src/nitro/communication/messages/parser/room/unit/RoomUnitIdleParser.ts create mode 100644 src/nitro/communication/messages/parser/room/unit/RoomUnitInfoParser.ts create mode 100644 src/nitro/communication/messages/parser/room/unit/RoomUnitNumberParser.ts create mode 100644 src/nitro/communication/messages/parser/room/unit/RoomUnitParser.ts create mode 100644 src/nitro/communication/messages/parser/room/unit/RoomUnitRemoveParser.ts create mode 100644 src/nitro/communication/messages/parser/room/unit/RoomUnitStatusAction.ts create mode 100644 src/nitro/communication/messages/parser/room/unit/RoomUnitStatusMessage.ts create mode 100644 src/nitro/communication/messages/parser/room/unit/RoomUnitStatusParser.ts create mode 100644 src/nitro/communication/messages/parser/room/unit/UserMessageData.ts create mode 100644 src/nitro/communication/messages/parser/room/unit/chat/FloodControlParser.ts create mode 100644 src/nitro/communication/messages/parser/room/unit/chat/RemainingMuteParser.ts create mode 100644 src/nitro/communication/messages/parser/room/unit/chat/RoomUnitChatParser.ts create mode 100644 src/nitro/communication/messages/parser/room/unit/chat/RoomUnitTypingParser.ts create mode 100644 src/nitro/communication/messages/parser/roomevents/RoomMutedParser.ts create mode 100644 src/nitro/communication/messages/parser/roomevents/WiredFurniActionParser.ts create mode 100644 src/nitro/communication/messages/parser/roomevents/WiredFurniConditionParser.ts create mode 100644 src/nitro/communication/messages/parser/roomevents/WiredFurniTriggerParser.ts create mode 100644 src/nitro/communication/messages/parser/roomevents/WiredOpenParser.ts create mode 100644 src/nitro/communication/messages/parser/roomevents/WiredRewardResultMessageParser.ts create mode 100644 src/nitro/communication/messages/parser/roomevents/WiredSaveSuccessParser.ts create mode 100644 src/nitro/communication/messages/parser/roomevents/WiredValidationErrorParser.ts create mode 100644 src/nitro/communication/messages/parser/security/AuthenticatedParser.ts create mode 100644 src/nitro/communication/messages/parser/user/IgnoreResultParser.ts create mode 100644 src/nitro/communication/messages/parser/user/IgnoredUsersParser.ts create mode 100644 src/nitro/communication/messages/parser/user/InClientLinkParser.ts create mode 100644 src/nitro/communication/messages/parser/user/access/UserPerksParser.ts create mode 100644 src/nitro/communication/messages/parser/user/access/UserPermissionsParser.ts create mode 100644 src/nitro/communication/messages/parser/user/data/UserCurrentBadgesParser.ts create mode 100644 src/nitro/communication/messages/parser/user/data/UserFigureParser.ts create mode 100644 src/nitro/communication/messages/parser/user/data/UserInfoDataParser.ts create mode 100644 src/nitro/communication/messages/parser/user/data/UserInfoParser.ts create mode 100644 src/nitro/communication/messages/parser/user/data/UserNameChangeMessageParser.ts create mode 100644 src/nitro/communication/messages/parser/user/data/UserProfileParser.ts create mode 100644 src/nitro/communication/messages/parser/user/data/UserRelationshipDataParser.ts create mode 100644 src/nitro/communication/messages/parser/user/data/UserRelationshipsParser.ts create mode 100644 src/nitro/communication/messages/parser/user/data/UserSettingsParser.ts create mode 100644 src/nitro/communication/messages/parser/user/inventory/currency/UserCreditsParser.ts create mode 100644 src/nitro/communication/messages/parser/user/inventory/currency/UserCurrencyParser.ts create mode 100644 src/nitro/communication/messages/parser/user/inventory/currency/UserCurrencyUpdateParser.ts create mode 100644 src/nitro/communication/messages/parser/user/inventory/subscription/UserSubscriptionParser.ts create mode 100644 src/nitro/communication/messages/parser/user/wardrobe/UserWardrobePageParser.ts create mode 100644 src/nitro/enums/RelationshipStatusEnum.ts create mode 100644 src/nitro/enums/ToolbarIconEnum.ts create mode 100644 src/nitro/events/NitroSettingsEvent.ts create mode 100644 src/nitro/events/NitroToolbarAnimateIconEvent.ts create mode 100644 src/nitro/events/NitroToolbarEvent.ts create mode 100644 src/nitro/externalInterface/LegacyExternalInterface.ts create mode 100644 src/nitro/game/GameMessageHandler.ts create mode 100644 src/nitro/localization/BadgeBaseAndLevel.ts create mode 100644 src/nitro/localization/INitroLocalizationManager.ts create mode 100644 src/nitro/localization/NitroLocalizationEvent.ts create mode 100644 src/nitro/localization/NitroLocalizationManager.ts create mode 100644 src/nitro/room/IGetImageListener.ts create mode 100644 src/nitro/room/IRoomContentListener.ts create mode 100644 src/nitro/room/IRoomCreator.ts create mode 100644 src/nitro/room/IRoomEngine.ts create mode 100644 src/nitro/room/IRoomEngineServices.ts create mode 100644 src/nitro/room/ISelectedRoomObjectData.ts create mode 100644 src/nitro/room/ImageResult.ts create mode 100644 src/nitro/room/PetColorResult.ts create mode 100644 src/nitro/room/RoomContentLoader.ts create mode 100644 src/nitro/room/RoomEngine.ts create mode 100644 src/nitro/room/RoomMessageHandler.ts create mode 100644 src/nitro/room/RoomObjectEventHandler.ts create mode 100644 src/nitro/room/RoomObjectLogicFactory.ts create mode 100644 src/nitro/room/RoomVariableEnum.ts create mode 100644 src/nitro/room/enums/FriendFurniEngravingWidgetType.ts create mode 100644 src/nitro/room/enums/RoomObjectPlacementSource.ts create mode 100644 src/nitro/room/events/RoomBackgroundColorEvent.ts create mode 100644 src/nitro/room/events/RoomEngineDimmerStateEvent.ts create mode 100644 src/nitro/room/events/RoomEngineEvent.ts create mode 100644 src/nitro/room/events/RoomEngineObjectEvent.ts create mode 100644 src/nitro/room/events/RoomEngineObjectPlacedEvent.ts create mode 100644 src/nitro/room/events/RoomEngineObjectPlacedOnUserEvent.ts create mode 100644 src/nitro/room/events/RoomEngineSamplePlaybackEvent.ts create mode 100644 src/nitro/room/events/RoomEngineTriggerWidgetEvent.ts create mode 100644 src/nitro/room/events/RoomObjectBadgeAssetEvent.ts create mode 100644 src/nitro/room/events/RoomObjectDataRequestEvent.ts create mode 100644 src/nitro/room/events/RoomObjectDimmerStateUpdateEvent.ts create mode 100644 src/nitro/room/events/RoomObjectFloorHoleEvent.ts create mode 100644 src/nitro/room/events/RoomObjectFurnitureActionEvent.ts create mode 100644 src/nitro/room/events/RoomObjectHSLColorEnableEvent.ts create mode 100644 src/nitro/room/events/RoomObjectHSLColorEnabledEvent.ts create mode 100644 src/nitro/room/events/RoomObjectMoveEvent.ts create mode 100644 src/nitro/room/events/RoomObjectSamplePlaybackEvent.ts create mode 100644 src/nitro/room/events/RoomObjectStateChangedEvent.ts create mode 100644 src/nitro/room/events/RoomObjectTileMouseEvent.ts create mode 100644 src/nitro/room/events/RoomObjectWallMouseEvent.ts create mode 100644 src/nitro/room/events/RoomObjectWidgetRequestEvent.ts create mode 100644 src/nitro/room/events/RoomToObjectOwnAvatarMoveEvent.ts create mode 100644 src/nitro/room/events/RoomZoomEvent.ts create mode 100644 src/nitro/room/messages/ObjectAdUpdateMessage.ts create mode 100644 src/nitro/room/messages/ObjectAvatarCarryObjectUpdateMessage.ts create mode 100644 src/nitro/room/messages/ObjectAvatarChatUpdateMessage.ts create mode 100644 src/nitro/room/messages/ObjectAvatarDanceUpdateMessage.ts create mode 100644 src/nitro/room/messages/ObjectAvatarEffectUpdateMessage.ts create mode 100644 src/nitro/room/messages/ObjectAvatarExperienceUpdateMessage.ts create mode 100644 src/nitro/room/messages/ObjectAvatarExpressionUpdateMessage.ts create mode 100644 src/nitro/room/messages/ObjectAvatarFigureUpdateMessage.ts create mode 100644 src/nitro/room/messages/ObjectAvatarFlatControlUpdateMessage.ts create mode 100644 src/nitro/room/messages/ObjectAvatarGestureUpdateMessage.ts create mode 100644 src/nitro/room/messages/ObjectAvatarGuideStatusUpdateMessage.ts create mode 100644 src/nitro/room/messages/ObjectAvatarMutedUpdateMessage.ts create mode 100644 src/nitro/room/messages/ObjectAvatarOwnMessage.ts create mode 100644 src/nitro/room/messages/ObjectAvatarPetGestureUpdateMessage.ts create mode 100644 src/nitro/room/messages/ObjectAvatarPlayerValueUpdateMessage.ts create mode 100644 src/nitro/room/messages/ObjectAvatarPlayingGameUpdateMessage.ts create mode 100644 src/nitro/room/messages/ObjectAvatarPostureUpdateMessage.ts create mode 100644 src/nitro/room/messages/ObjectAvatarSelectedMessage.ts create mode 100644 src/nitro/room/messages/ObjectAvatarSignUpdateMessage.ts create mode 100644 src/nitro/room/messages/ObjectAvatarSleepUpdateMessage.ts create mode 100644 src/nitro/room/messages/ObjectAvatarTypingUpdateMessage.ts create mode 100644 src/nitro/room/messages/ObjectAvatarUpdateMessage.ts create mode 100644 src/nitro/room/messages/ObjectAvatarUseObjectUpdateMessage.ts create mode 100644 src/nitro/room/messages/ObjectDataUpdateMessage.ts create mode 100644 src/nitro/room/messages/ObjectGroupBadgeUpdateMessage.ts create mode 100644 src/nitro/room/messages/ObjectHeightUpdateMessage.ts create mode 100644 src/nitro/room/messages/ObjectItemDataUpdateMessage.ts create mode 100644 src/nitro/room/messages/ObjectModelDataUpdateMessage.ts create mode 100644 src/nitro/room/messages/ObjectMoveUpdateMessage.ts create mode 100644 src/nitro/room/messages/ObjectRoomColorUpdateMessage.ts create mode 100644 src/nitro/room/messages/ObjectRoomFloorHoleUpdateMessage.ts create mode 100644 src/nitro/room/messages/ObjectRoomMapUpdateMessage.ts create mode 100644 src/nitro/room/messages/ObjectRoomMaskUpdateMessage.ts create mode 100644 src/nitro/room/messages/ObjectRoomPlanePropertyUpdateMessage.ts create mode 100644 src/nitro/room/messages/ObjectRoomPlaneVisibilityUpdateMessage.ts create mode 100644 src/nitro/room/messages/ObjectRoomUpdateMessage.ts create mode 100644 src/nitro/room/messages/ObjectSelectedMessage.ts create mode 100644 src/nitro/room/messages/ObjectStateUpdateMessage.ts create mode 100644 src/nitro/room/messages/ObjectTileCursorUpdateMessage.ts create mode 100644 src/nitro/room/messages/ObjectVisibilityUpdateMessage.ts create mode 100644 src/nitro/room/object/RoomFloorHole.ts create mode 100644 src/nitro/room/object/RoomMapData.ts create mode 100644 src/nitro/room/object/RoomMapMaskData.ts create mode 100644 src/nitro/room/object/RoomObjectCategory.ts create mode 100644 src/nitro/room/object/RoomObjectLogicType.ts create mode 100644 src/nitro/room/object/RoomObjectOperationType.ts create mode 100644 src/nitro/room/object/RoomObjectType.ts create mode 100644 src/nitro/room/object/RoomObjectUserType.ts create mode 100644 src/nitro/room/object/RoomObjectVariable.ts create mode 100644 src/nitro/room/object/RoomObjectVisualizationFactory.ts create mode 100644 src/nitro/room/object/RoomObjectVisualizationType.ts create mode 100644 src/nitro/room/object/RoomPlaneBitmapMaskData.ts create mode 100644 src/nitro/room/object/RoomPlaneBitmapMaskParser.ts create mode 100644 src/nitro/room/object/RoomPlaneData.ts create mode 100644 src/nitro/room/object/RoomPlaneMaskData.ts create mode 100644 src/nitro/room/object/RoomPlaneParser.ts create mode 100644 src/nitro/room/object/RoomWallData.ts create mode 100644 src/nitro/room/object/data/IObjectData.ts create mode 100644 src/nitro/room/object/data/ObjectDataBase.ts create mode 100644 src/nitro/room/object/data/ObjectDataFactory.ts create mode 100644 src/nitro/room/object/data/ObjectDataFlags.ts create mode 100644 src/nitro/room/object/data/ObjectDataKey.ts create mode 100644 src/nitro/room/object/data/type/CrackableDataType.ts create mode 100644 src/nitro/room/object/data/type/EmptyDataType.ts create mode 100644 src/nitro/room/object/data/type/HighScoreData.ts create mode 100644 src/nitro/room/object/data/type/HighScoreDataType.ts create mode 100644 src/nitro/room/object/data/type/LegacyDataType.ts create mode 100644 src/nitro/room/object/data/type/MapDataType.ts create mode 100644 src/nitro/room/object/data/type/NumberDataType.ts create mode 100644 src/nitro/room/object/data/type/StringDataType.ts create mode 100644 src/nitro/room/object/data/type/VoteDataType.ts create mode 100644 src/nitro/room/object/logic/MovingObjectLogic.ts create mode 100644 src/nitro/room/object/logic/avatar/AvatarLogic.ts create mode 100644 src/nitro/room/object/logic/furniture/FurnitureBadgeDisplayLogic.ts create mode 100644 src/nitro/room/object/logic/furniture/FurnitureChangeStateWhenStepOnLogic.ts create mode 100644 src/nitro/room/object/logic/furniture/FurnitureCounterClockLogic.ts create mode 100644 src/nitro/room/object/logic/furniture/FurnitureCrackableLogic.ts create mode 100644 src/nitro/room/object/logic/furniture/FurnitureCreditLogic.ts create mode 100644 src/nitro/room/object/logic/furniture/FurnitureCustomStackHeightLogic.ts create mode 100644 src/nitro/room/object/logic/furniture/FurnitureDiceLogic.ts create mode 100644 src/nitro/room/object/logic/furniture/FurnitureEditableInternalLinkLogic.ts create mode 100644 src/nitro/room/object/logic/furniture/FurnitureEditableRoomLinkLogic.ts create mode 100644 src/nitro/room/object/logic/furniture/FurnitureExternalImageLogic.ts create mode 100644 src/nitro/room/object/logic/furniture/FurnitureFireworksLogic.ts create mode 100644 src/nitro/room/object/logic/furniture/FurnitureFloorHoleLogic.ts create mode 100644 src/nitro/room/object/logic/furniture/FurnitureFriendLogic.ts create mode 100644 src/nitro/room/object/logic/furniture/FurnitureGuildCustomizedLogic.ts create mode 100644 src/nitro/room/object/logic/furniture/FurnitureHabboWheelLogic.ts create mode 100644 src/nitro/room/object/logic/furniture/FurnitureHighScoreLogic.ts create mode 100644 src/nitro/room/object/logic/furniture/FurnitureHockeyScoreLogic.ts create mode 100644 src/nitro/room/object/logic/furniture/FurnitureIceStormLogic.ts create mode 100644 src/nitro/room/object/logic/furniture/FurnitureLogic.ts create mode 100644 src/nitro/room/object/logic/furniture/FurnitureMannequinLogic.ts create mode 100644 src/nitro/room/object/logic/furniture/FurnitureMultiHeightLogic.ts create mode 100644 src/nitro/room/object/logic/furniture/FurnitureMultiStateLogic.ts create mode 100644 src/nitro/room/object/logic/furniture/FurnitureOneWayDoorLogic.ts create mode 100644 src/nitro/room/object/logic/furniture/FurniturePetCustomizationLogic.ts create mode 100644 src/nitro/room/object/logic/furniture/FurniturePresentLogic.ts create mode 100644 src/nitro/room/object/logic/furniture/FurniturePurchaseableClothingLogic.ts create mode 100644 src/nitro/room/object/logic/furniture/FurniturePushableLogic.ts create mode 100644 src/nitro/room/object/logic/furniture/FurnitureRoomBackgroundColorLogic.ts create mode 100644 src/nitro/room/object/logic/furniture/FurnitureRoomBackgroundLogic.ts create mode 100644 src/nitro/room/object/logic/furniture/FurnitureRoomBillboardLogic.ts create mode 100644 src/nitro/room/object/logic/furniture/FurnitureRoomBrandingLogic.ts create mode 100644 src/nitro/room/object/logic/furniture/FurnitureRoomDimmerLogic.ts create mode 100644 src/nitro/room/object/logic/furniture/FurnitureScoreLogic.ts create mode 100644 src/nitro/room/object/logic/furniture/FurnitureSoundBlockLogic.ts create mode 100644 src/nitro/room/object/logic/furniture/FurnitureStickieLogic.ts create mode 100644 src/nitro/room/object/logic/furniture/FurnitureTrophyLogic.ts create mode 100644 src/nitro/room/object/logic/furniture/FurnitureVoteCounterLogic.ts create mode 100644 src/nitro/room/object/logic/furniture/FurnitureVoteMajorityLogic.ts create mode 100644 src/nitro/room/object/logic/furniture/FurnitureWindowLogic.ts create mode 100644 src/nitro/room/object/logic/furniture/FurnitureYoutubeLogic.ts create mode 100644 src/nitro/room/object/logic/pet/PetLogic.ts create mode 100644 src/nitro/room/object/logic/room/RoomLogic.ts create mode 100644 src/nitro/room/object/logic/room/SelectionArrowLogic.ts create mode 100644 src/nitro/room/object/logic/room/TileCursorLogic.ts create mode 100644 src/nitro/room/object/visualization/avatar/AvatarVisualization.ts create mode 100644 src/nitro/room/object/visualization/avatar/AvatarVisualizationData.ts create mode 100644 src/nitro/room/object/visualization/avatar/additions/ExpressionAddition.ts create mode 100644 src/nitro/room/object/visualization/avatar/additions/ExpressionAdditionFactory.ts create mode 100644 src/nitro/room/object/visualization/avatar/additions/FloatingHeartAddition.ts create mode 100644 src/nitro/room/object/visualization/avatar/additions/FloatingIdleZAddition.ts create mode 100644 src/nitro/room/object/visualization/avatar/additions/IAvatarAddition.ts create mode 100644 src/nitro/room/object/visualization/avatar/additions/IExpressionAddition.ts create mode 100644 src/nitro/room/object/visualization/avatar/additions/MutedBubbleAddition.ts create mode 100644 src/nitro/room/object/visualization/avatar/additions/NumberBubbleAddition.ts create mode 100644 src/nitro/room/object/visualization/avatar/additions/TypingBubbleAddition.ts create mode 100644 src/nitro/room/object/visualization/data/AnimationData.ts create mode 100644 src/nitro/room/object/visualization/data/AnimationFrame.ts create mode 100644 src/nitro/room/object/visualization/data/AnimationFrameData.ts create mode 100644 src/nitro/room/object/visualization/data/AnimationFrameDirectionalData.ts create mode 100644 src/nitro/room/object/visualization/data/AnimationFrameSequenceData.ts create mode 100644 src/nitro/room/object/visualization/data/AnimationLayerData.ts create mode 100644 src/nitro/room/object/visualization/data/AnimationSizeData.ts create mode 100644 src/nitro/room/object/visualization/data/AnimationStateData.ts create mode 100644 src/nitro/room/object/visualization/data/ColorData.ts create mode 100644 src/nitro/room/object/visualization/data/DirectionData.ts create mode 100644 src/nitro/room/object/visualization/data/DirectionalOffsetData.ts create mode 100644 src/nitro/room/object/visualization/data/LayerData.ts create mode 100644 src/nitro/room/object/visualization/data/PetSizeData.ts create mode 100644 src/nitro/room/object/visualization/data/SizeData.ts create mode 100644 src/nitro/room/object/visualization/furniture/FurnitureAnimatedVisualization.ts create mode 100644 src/nitro/room/object/visualization/furniture/FurnitureAnimatedVisualizationData.ts create mode 100644 src/nitro/room/object/visualization/furniture/FurnitureBBVisualization.ts create mode 100644 src/nitro/room/object/visualization/furniture/FurnitureBadgeDisplayVisualization.ts create mode 100644 src/nitro/room/object/visualization/furniture/FurnitureBottleVisualization.ts create mode 100644 src/nitro/room/object/visualization/furniture/FurnitureBrandedImageVisualization.ts create mode 100644 src/nitro/room/object/visualization/furniture/FurnitureBuilderPlaceholderVisualization.ts create mode 100644 src/nitro/room/object/visualization/furniture/FurnitureCounterClockVisualization.ts create mode 100644 src/nitro/room/object/visualization/furniture/FurnitureCuboidVisualization.ts create mode 100644 src/nitro/room/object/visualization/furniture/FurnitureDynamicThumbnailVisualization.ts create mode 100644 src/nitro/room/object/visualization/furniture/FurnitureExternalImageVisualization.ts create mode 100644 src/nitro/room/object/visualization/furniture/FurnitureFireworksVisualization.ts create mode 100644 src/nitro/room/object/visualization/furniture/FurnitureGiftWrappedFireworksVisualization.ts create mode 100644 src/nitro/room/object/visualization/furniture/FurnitureGiftWrappedVisualization.ts create mode 100644 src/nitro/room/object/visualization/furniture/FurnitureGuildCustomizedVisualization.ts create mode 100644 src/nitro/room/object/visualization/furniture/FurnitureGuildIsometricBadgeVisualization.ts create mode 100644 src/nitro/room/object/visualization/furniture/FurnitureHabboWheelVisualization.ts create mode 100644 src/nitro/room/object/visualization/furniture/FurnitureMannequinVisualization.ts create mode 100644 src/nitro/room/object/visualization/furniture/FurnitureMannequinVisualizationData.ts create mode 100644 src/nitro/room/object/visualization/furniture/FurnitureParticleSystemEmitter.ts create mode 100644 src/nitro/room/object/visualization/furniture/FurnitureParticleSystemParticle.ts create mode 100644 src/nitro/room/object/visualization/furniture/FurniturePartyBeamerVisualization.ts create mode 100644 src/nitro/room/object/visualization/furniture/FurniturePlanetSystemVisualization.ts create mode 100644 src/nitro/room/object/visualization/furniture/FurniturePosterVisualization.ts create mode 100644 src/nitro/room/object/visualization/furniture/FurnitureQueueTileVisualization.ts create mode 100644 src/nitro/room/object/visualization/furniture/FurnitureResettingAnimatedVisualization.ts create mode 100644 src/nitro/room/object/visualization/furniture/FurnitureRoomBackgroundVisualization.ts create mode 100644 src/nitro/room/object/visualization/furniture/FurnitureScoreBoardVisualization.ts create mode 100644 src/nitro/room/object/visualization/furniture/FurnitureSoundBlockVisualization.ts create mode 100644 src/nitro/room/object/visualization/furniture/FurnitureStickieVisualization.ts create mode 100644 src/nitro/room/object/visualization/furniture/FurnitureThumbnailVisualization.ts create mode 100644 src/nitro/room/object/visualization/furniture/FurnitureValRandomizerVisualization.ts create mode 100644 src/nitro/room/object/visualization/furniture/FurnitureVisualization.ts create mode 100644 src/nitro/room/object/visualization/furniture/FurnitureVisualizationData.ts create mode 100644 src/nitro/room/object/visualization/furniture/FurnitureVoteCounterVisualization.ts create mode 100644 src/nitro/room/object/visualization/furniture/FurnitureVoteMajorityVisualization.ts create mode 100644 src/nitro/room/object/visualization/furniture/FurnitureWaterAreaVisualization.ts create mode 100644 src/nitro/room/object/visualization/furniture/FurnitureYoutubeVisualization.ts create mode 100644 src/nitro/room/object/visualization/pet/PetVisualization.ts create mode 100644 src/nitro/room/object/visualization/pet/PetVisualizationData.ts create mode 100644 src/nitro/room/object/visualization/room/PlaneDrawingData.ts create mode 100644 src/nitro/room/object/visualization/room/RoomPlane.ts create mode 100644 src/nitro/room/object/visualization/room/RoomPlaneBitmapMask.ts create mode 100644 src/nitro/room/object/visualization/room/RoomPlaneRectangleMask.ts create mode 100644 src/nitro/room/object/visualization/room/RoomVisualization.ts create mode 100644 src/nitro/room/object/visualization/room/RoomVisualizationData.ts create mode 100644 src/nitro/room/object/visualization/room/TileCursorVisualization.ts create mode 100644 src/nitro/room/object/visualization/room/mask/PlaneMask.ts create mode 100644 src/nitro/room/object/visualization/room/mask/PlaneMaskBitmap.ts create mode 100644 src/nitro/room/object/visualization/room/mask/PlaneMaskManager.ts create mode 100644 src/nitro/room/object/visualization/room/mask/PlaneMaskVisualization.ts create mode 100644 src/nitro/room/object/visualization/room/rasterizer/IPlaneRasterizer.ts create mode 100644 src/nitro/room/object/visualization/room/rasterizer/animated/AnimationItem.ts create mode 100644 src/nitro/room/object/visualization/room/rasterizer/animated/LandscapePlane.ts create mode 100644 src/nitro/room/object/visualization/room/rasterizer/animated/LandscapeRasterizer.ts create mode 100644 src/nitro/room/object/visualization/room/rasterizer/animated/PlaneVisualizationAnimationLayer.ts create mode 100644 src/nitro/room/object/visualization/room/rasterizer/basic/FloorPlane.ts create mode 100644 src/nitro/room/object/visualization/room/rasterizer/basic/FloorRasterizer.ts create mode 100644 src/nitro/room/object/visualization/room/rasterizer/basic/Plane.ts create mode 100644 src/nitro/room/object/visualization/room/rasterizer/basic/PlaneMaterial.ts create mode 100644 src/nitro/room/object/visualization/room/rasterizer/basic/PlaneMaterialCell.ts create mode 100644 src/nitro/room/object/visualization/room/rasterizer/basic/PlaneMaterialCellColumn.ts create mode 100644 src/nitro/room/object/visualization/room/rasterizer/basic/PlaneMaterialCellMatrix.ts create mode 100644 src/nitro/room/object/visualization/room/rasterizer/basic/PlaneRasterizer.ts create mode 100644 src/nitro/room/object/visualization/room/rasterizer/basic/PlaneTexture.ts create mode 100644 src/nitro/room/object/visualization/room/rasterizer/basic/PlaneTextureBitmap.ts create mode 100644 src/nitro/room/object/visualization/room/rasterizer/basic/PlaneVisualization.ts create mode 100644 src/nitro/room/object/visualization/room/rasterizer/basic/PlaneVisualizationLayer.ts create mode 100644 src/nitro/room/object/visualization/room/rasterizer/basic/WallPlane.ts create mode 100644 src/nitro/room/object/visualization/room/rasterizer/basic/WallRasterizer.ts create mode 100644 src/nitro/room/object/visualization/room/utils/PlaneBitmapData.ts create mode 100644 src/nitro/room/object/visualization/room/utils/Randomizer.ts create mode 100644 src/nitro/room/preview/RoomPreviewer.ts create mode 100644 src/nitro/room/utils/FurnitureData.ts create mode 100644 src/nitro/room/utils/FurnitureStackingHeightMap.ts create mode 100644 src/nitro/room/utils/LegacyWallGeometry.ts create mode 100644 src/nitro/room/utils/ObjectRolling.ts create mode 100644 src/nitro/room/utils/RoomCamera.ts create mode 100644 src/nitro/room/utils/RoomData.ts create mode 100644 src/nitro/room/utils/RoomInstanceData.ts create mode 100644 src/nitro/room/utils/RoomObjectBadgeImageAssetListener.ts create mode 100644 src/nitro/room/utils/SelectedRoomObjectData.ts create mode 100644 src/nitro/room/utils/SpriteDataCollector.ts create mode 100644 src/nitro/room/utils/TileObjectMap.ts create mode 100644 src/nitro/session/BadgeImageManager.ts create mode 100644 src/nitro/session/BadgeInfo.ts create mode 100644 src/nitro/session/HabboClubLevelEnum.ts create mode 100644 src/nitro/session/IRoomHandlerListener.ts create mode 100644 src/nitro/session/IRoomSession.ts create mode 100644 src/nitro/session/IRoomSessionManager.ts create mode 100644 src/nitro/session/ISessionDataManager.ts create mode 100644 src/nitro/session/IgnoredUsersManager.ts create mode 100644 src/nitro/session/RoomPetData.ts create mode 100644 src/nitro/session/RoomSession.ts create mode 100644 src/nitro/session/RoomSessionManager.ts create mode 100644 src/nitro/session/RoomUserData.ts create mode 100644 src/nitro/session/SessionDataManager.ts create mode 100644 src/nitro/session/UserDataManager.ts create mode 100644 src/nitro/session/enum/GenericErrorEnum.ts create mode 100644 src/nitro/session/enum/RoomControllerLevel.ts create mode 100644 src/nitro/session/enum/RoomTradingLevelEnum.ts create mode 100644 src/nitro/session/enum/SecurityLevel.ts create mode 100644 src/nitro/session/events/BadgeImageReadyEvent.ts create mode 100644 src/nitro/session/events/MysteryBoxKeysUpdateEvent.ts create mode 100644 src/nitro/session/events/PerksUpdatedEvent.ts create mode 100644 src/nitro/session/events/RoomSessionChatEvent.ts create mode 100644 src/nitro/session/events/RoomSessionConfirmPetBreedingEvent.ts create mode 100644 src/nitro/session/events/RoomSessionConfirmPetBreedingResultEvent.ts create mode 100644 src/nitro/session/events/RoomSessionDanceEvent.ts create mode 100644 src/nitro/session/events/RoomSessionDimmerPresetsEvent.ts create mode 100644 src/nitro/session/events/RoomSessionDimmerPresetsEventPresetItem.ts create mode 100644 src/nitro/session/events/RoomSessionDoorbellEvent.ts create mode 100644 src/nitro/session/events/RoomSessionErrorMessageEvent.ts create mode 100644 src/nitro/session/events/RoomSessionEvent.ts create mode 100644 src/nitro/session/events/RoomSessionFavouriteGroupUpdateEvent.ts create mode 100644 src/nitro/session/events/RoomSessionFriendRequestEvent.ts create mode 100644 src/nitro/session/events/RoomSessionNestBreedingSuccessEvent.ts create mode 100644 src/nitro/session/events/RoomSessionPetBreedingEvent.ts create mode 100644 src/nitro/session/events/RoomSessionPetBreedingResultEvent.ts create mode 100644 src/nitro/session/events/RoomSessionPetCommandsUpdateEvent.ts create mode 100644 src/nitro/session/events/RoomSessionPetFigureUpdateEvent.ts create mode 100644 src/nitro/session/events/RoomSessionPetInfoUpdateEvent.ts create mode 100644 src/nitro/session/events/RoomSessionPetLevelUpdateEvent.ts create mode 100644 src/nitro/session/events/RoomSessionPetPackageEvent.ts create mode 100644 src/nitro/session/events/RoomSessionPetStatusUpdateEvent.ts create mode 100644 src/nitro/session/events/RoomSessionPollEvent.ts create mode 100644 src/nitro/session/events/RoomSessionPresentEvent.ts create mode 100644 src/nitro/session/events/RoomSessionPropertyUpdateEvent.ts create mode 100644 src/nitro/session/events/RoomSessionQueueEvent.ts create mode 100644 src/nitro/session/events/RoomSessionUserBadgesEvent.ts create mode 100644 src/nitro/session/events/RoomSessionUserDataUpdateEvent.ts create mode 100644 src/nitro/session/events/RoomSessionUserFigureUpdateEvent.ts create mode 100644 src/nitro/session/events/RoomSessionUserTagsEvent.ts create mode 100644 src/nitro/session/events/RoomSessionWordQuizEvent.ts create mode 100644 src/nitro/session/events/SessionDataPreferencesEvent.ts create mode 100644 src/nitro/session/events/UserNameUpdateEvent.ts create mode 100644 src/nitro/session/events/_Str_3051.ts create mode 100644 src/nitro/session/furniture/FurnitureData.ts create mode 100644 src/nitro/session/furniture/FurnitureDataParser.ts create mode 100644 src/nitro/session/furniture/FurnitureType.ts create mode 100644 src/nitro/session/furniture/IFurnitureData.ts create mode 100644 src/nitro/session/furniture/IFurnitureDataListener.ts create mode 100644 src/nitro/session/handler/BaseHandler.ts create mode 100644 src/nitro/session/handler/GenericErrorHandler.ts create mode 100644 src/nitro/session/handler/RoomChatHandler.ts create mode 100644 src/nitro/session/handler/RoomDataHandler.ts create mode 100644 src/nitro/session/handler/RoomDimmerPresetsHandler.ts create mode 100644 src/nitro/session/handler/RoomPermissionsHandler.ts create mode 100644 src/nitro/session/handler/RoomPresentHandler.ts create mode 100644 src/nitro/session/handler/RoomSessionHandler.ts create mode 100644 src/nitro/session/handler/RoomUsersHandler.ts create mode 100644 src/nitro/session/product/IProductData.ts create mode 100644 src/nitro/session/product/IProductDataListener.ts create mode 100644 src/nitro/session/product/ProductData.ts create mode 100644 src/nitro/session/product/ProductDataParser.ts create mode 100644 src/nitro/ui/IRoomWidgetHandler.ts create mode 100644 src/nitro/ui/IRoomWidgetHandlerContainer.ts create mode 100644 src/nitro/ui/MouseEventType.ts create mode 100644 src/nitro/ui/TouchEventType.ts create mode 100644 src/nitro/ui/widget/ConversionTrackingWidget.ts create mode 100644 src/nitro/ui/widget/IRoomWidget.ts create mode 100644 src/nitro/ui/widget/IRoomWidgetMessageListener.ts create mode 100644 src/nitro/ui/widget/enums/AvatarExpressionEnum.ts create mode 100644 src/nitro/ui/widget/enums/FriendWidgetEngravingWidgetTypeEnum.ts create mode 100644 src/nitro/ui/widget/enums/RoomWidgetEnum.ts create mode 100644 src/nitro/ui/widget/enums/RoomWidgetEnumItemExtradataParameter.ts create mode 100644 src/nitro/ui/widget/enums/RoomWidgetFurniInfoUsagePolicyEnum.ts create mode 100644 src/nitro/ui/widget/enums/SystemChatStyleEnum.ts create mode 100644 src/nitro/ui/widget/events/RoomWidgetUpdateEvent.ts create mode 100644 src/nitro/ui/widget/messages/RoomWidgetMessage.ts create mode 100644 src/nitro/utils/FigureDataContainer.ts create mode 100644 src/nitro/utils/FixedSizeStack.ts create mode 100644 src/nitro/utils/FriendlyTime.ts create mode 100644 src/nitro/utils/FurniId.ts create mode 100644 src/nitro/utils/HabboWebTools.ts create mode 100644 src/nitro/utils/WebGL.ts create mode 100644 src/nitro/window/motion/Callback.ts create mode 100644 src/nitro/window/motion/Combo.ts create mode 100644 src/nitro/window/motion/Dispose.ts create mode 100644 src/nitro/window/motion/DropBounce.ts create mode 100644 src/nitro/window/motion/Ease.ts create mode 100644 src/nitro/window/motion/EaseOut.ts create mode 100644 src/nitro/window/motion/EaseRate.ts create mode 100644 src/nitro/window/motion/Interval.ts create mode 100644 src/nitro/window/motion/JumpBy.ts create mode 100644 src/nitro/window/motion/Motion.ts create mode 100644 src/nitro/window/motion/Motions.ts create mode 100644 src/nitro/window/motion/MoveBy.ts create mode 100644 src/nitro/window/motion/MoveTo.ts create mode 100644 src/nitro/window/motion/Queue.ts create mode 100644 src/nitro/window/motion/ResizeTo.ts create mode 100644 src/nitro/window/motion/Wait.ts create mode 100644 src/room/IRoomInstance.ts create mode 100644 src/room/IRoomInstanceContainer.ts create mode 100644 src/room/IRoomManager.ts create mode 100644 src/room/IRoomManagerListener.ts create mode 100644 src/room/IRoomObjectManager.ts create mode 100644 src/room/RoomInstance.ts create mode 100644 src/room/RoomManager.ts create mode 100644 src/room/RoomObjectManager.ts create mode 100644 src/room/data/RoomObjectSpriteData.ts create mode 100644 src/room/events/RoomContentLoadedEvent.ts create mode 100644 src/room/events/RoomObjectEvent.ts create mode 100644 src/room/events/RoomObjectMouseEvent.ts create mode 100644 src/room/events/RoomSpriteMouseEvent.ts create mode 100644 src/room/events/RoomToObjectEvent.ts create mode 100644 src/room/messages/RoomObjectUpdateMessage.ts create mode 100644 src/room/object/IRoomObject.ts create mode 100644 src/room/object/IRoomObjectController.ts create mode 100644 src/room/object/IRoomObjectModel.ts create mode 100644 src/room/object/IRoomObjectModelController.ts create mode 100644 src/room/object/RoomObject.ts create mode 100644 src/room/object/RoomObjectModel.ts create mode 100644 src/room/object/enum/AlphaTolerance.ts create mode 100644 src/room/object/enum/RoomObjectSpriteType.ts create mode 100644 src/room/object/logic/IRoomObjectEventHandler.ts create mode 100644 src/room/object/logic/IRoomObjectLogicFactory.ts create mode 100644 src/room/object/logic/IRoomObjectMouseHandler.ts create mode 100644 src/room/object/logic/RoomObjectLogicBase.ts create mode 100644 src/room/object/visualization/IPlaneDrawingData.ts create mode 100644 src/room/object/visualization/IPlaneVisualization.ts create mode 100644 src/room/object/visualization/IRoomObjectGraphicVisualization.ts create mode 100644 src/room/object/visualization/IRoomObjectSprite.ts create mode 100644 src/room/object/visualization/IRoomObjectSpriteVisualization.ts create mode 100644 src/room/object/visualization/IRoomObjectVisualization.ts create mode 100644 src/room/object/visualization/IRoomObjectVisualizationData.ts create mode 100644 src/room/object/visualization/IRoomObjectVisualizationFactory.ts create mode 100644 src/room/object/visualization/IRoomPlane.ts create mode 100644 src/room/object/visualization/ISortableSprite.ts create mode 100644 src/room/object/visualization/RoomObjectSprite.ts create mode 100644 src/room/object/visualization/RoomObjectSpriteVisualization.ts create mode 100644 src/room/object/visualization/utils/GraphicAsset.ts create mode 100644 src/room/object/visualization/utils/GraphicAssetCollection.ts create mode 100644 src/room/object/visualization/utils/GraphicAssetPalette.ts create mode 100644 src/room/object/visualization/utils/IGraphicAsset.ts create mode 100644 src/room/object/visualization/utils/IGraphicAssetCollection.ts create mode 100644 src/room/renderer/IRoomCanvasMouseListener.ts create mode 100644 src/room/renderer/IRoomRenderer.ts create mode 100644 src/room/renderer/IRoomRendererBase.ts create mode 100644 src/room/renderer/IRoomRendererFactory.ts create mode 100644 src/room/renderer/IRoomRenderingCanvas.ts create mode 100644 src/room/renderer/IRoomSpriteCanvasContainer.ts create mode 100644 src/room/renderer/RoomRenderer.ts create mode 100644 src/room/renderer/RoomRendererFactory.ts create mode 100644 src/room/renderer/RoomSpriteCanvas.ts create mode 100644 src/room/renderer/cache/RoomObjectCache.ts create mode 100644 src/room/renderer/cache/RoomObjectCacheItem.ts create mode 100644 src/room/renderer/cache/RoomObjectLocationCacheItem.ts create mode 100644 src/room/renderer/cache/RoomObjectSortableSpriteCacheItem.ts create mode 100644 src/room/renderer/utils/ExtendedSprite.ts create mode 100644 src/room/renderer/utils/ObjectMouseData.ts create mode 100644 src/room/renderer/utils/SortableSprite.ts create mode 100644 src/room/utils/ColorConverter.ts create mode 100644 src/room/utils/IRoomGeometry.ts create mode 100644 src/room/utils/IVector3D.ts create mode 100644 src/room/utils/NumberBank.ts create mode 100644 src/room/utils/PointMath.ts create mode 100644 src/room/utils/Rasterizer.ts create mode 100644 src/room/utils/RoomEnterEffect.ts create mode 100644 src/room/utils/RoomGeometry.ts create mode 100644 src/room/utils/RoomId.ts create mode 100644 src/room/utils/SpriteUtilities.ts create mode 100644 src/room/utils/TextureUtils.ts create mode 100644 src/room/utils/Vector3d.ts create mode 100644 tsconfig.json diff --git a/.browserslistrc b/.browserslistrc new file mode 100644 index 00000000..0ccadaf3 --- /dev/null +++ b/.browserslistrc @@ -0,0 +1,18 @@ +# This file is used by the build system to adjust CSS and JS output to support the specified browsers below. +# For additional information regarding the format and rule options, please see: +# https://github.com/browserslist/browserslist#queries + +# For the full list of supported browsers by the Angular framework, please see: +# https://angular.io/guide/browser-support + +# You can see what browsers were selected by your queries by running: +# npx browserslist + +last 1 Chrome version +last 1 Firefox version +last 2 Edge major versions +last 2 Safari major versions +last 2 iOS major versions +Firefox ESR +not IE 9-10 # Angular support for IE 9-10 has been deprecated and will be removed as of Angular v11. To opt-in, remove the 'not' prefix on this line. +not IE 11 # Angular supports IE 11 only as an opt-in. To opt-in, remove the 'not' prefix on this line. diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..07926923 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,16 @@ +# Editor configuration, see https://editorconfig.org +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 4 +insert_final_newline = true +trim_trailing_whitespace = true + +[*.ts] +quote_type = single + +[*.md] +max_line_length = off +trim_trailing_whitespace = false diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 00000000..75a1859d --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,132 @@ +{ + "env": { + "browser": true, + "es2021": true, + "node": true + }, + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended" + ], + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaVersion": 12, + "sourceType": "module" + }, + "plugins": [ + "@typescript-eslint" + ], + "rules": { + "indent": [ + "error", + 4, + { + "SwitchCase": 1 + } + ], + "no-trailing-spaces": [ + "error", + { + "skipBlankLines": false, + "ignoreComments": true + } + ], + "linebreak-style": [ + "off" + ], + "quotes": [ + "error", + "single" + ], + "semi": [ + "error", + "always" + ], + "brace-style": [ + "error", + "allman" + ], + "object-curly-spacing": [ + "error", + "always" + ], + "keyword-spacing": [ + "error", + { + "overrides": + { + "if": + { + "after": false + }, + "for": + { + "after": false + }, + "while": + { + "after": false + }, + "switch": + { + "after": false + } + } + } + ], + "@typescript-eslint/no-explicit-any": [ + "off" + ], + "@typescript-eslint/explicit-module-boundary-types": [ + "off", + { + "allowedNames": [ + "getMessageArray" + ] + } + ], + "@typescript-eslint/ban-ts-comment": [ + "off" + ], + "@typescript-eslint/no-empty-function": [ + "error", + { + "allow": [ + "functions", + "arrowFunctions", + "generatorFunctions", + "methods", + "generatorMethods", + "constructors" + ] + } + ], + "@typescript-eslint/no-unused-vars": [ + "off" + ], + "@typescript-eslint/no-inferrable-types": [ + "error", + { + "ignoreParameters": true, + "ignoreProperties": true + } + ], + "@typescript-eslint/ban-types": [ + "error", + { + "types": + { + "String": true, + "Boolean": true, + "Number": true, + "Symbol": true, + "{}": false, + "Object": false, + "object": false, + "Function": false + }, + "extendDefaults": true + } + ] + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..1413af91 --- /dev/null +++ b/.gitignore @@ -0,0 +1,51 @@ +# See http://help.github.com/ignore-files/ for more about ignoring files. + +# compiled output +/dist +/tmp +/out-tsc +# Only exists if Bazel was run +/bazel-out + +# dependencies +/node_modules + +# profiling files +chrome-profiler-events*.json +speed-measure-plugin*.json + +# IDEs and editors +/.idea +.project +.classpath +.c9/ +*.launch +.settings/ +*.sublime-workspace + +# IDE - VSCode +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +.history/* + +# misc +/.sass-cache +/connect.lock +/coverage +/libpeerconnection.log +npm-debug.log +yarn-error.log +testem.log +/typings +.git + +# System Files +.DS_Store +Thumbs.db + +*.zip +*.as +*.bin diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 00000000..7072af81 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,30 @@ +image: node:15.6 + +stages: + - test + - build + + +ESLinter: + stage: test + script: + - npm i + - node ./node_modules/eslint/bin/eslint.js src/ + cache: + key: ${CI_COMMIT_BRANCH} + paths: + - node_modules + +Build Nitro: + stage: build + script: + - npm i + - npm run build-prod + cache: + key: ${CI_COMMIT_BRANCH} + paths: + - node_modules + artifacts: + expire_in: 2 weeks + paths: + - dist/* diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..7b328b85 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,16 @@ +{ + "typescript.tsdk": "node_modules\\typescript\\lib", + "typescript.preferences.importModuleSpecifier": "relative", + "typescript.preferences.quoteStyle": "single", + "typescript.format.placeOpenBraceOnNewLineForControlBlocks": true, + "typescript.format.placeOpenBraceOnNewLineForFunctions": true, + "editor.codeActionsOnSave": { + "source.fixAll": true, + "source.organizeImports": true, + }, + "emmet.showExpandedAbbreviation": "never", + "git.ignoreLimitWarning": true, + "files.eol": "\n", + "files.insertFinalNewline": true, + "files.trimFinalNewlines": true +} diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..f288702d --- /dev/null +++ b/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program 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. + + This program 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 this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/index.ts b/index.ts new file mode 100644 index 00000000..8420b109 --- /dev/null +++ b/index.ts @@ -0,0 +1 @@ +export * from './src'; diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000..2ea7846f --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1747 @@ +{ + "name": "nitro-renderer", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "dev": true + }, + "@babel/highlight": { + "version": "7.13.10", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.13.10.tgz", + "integrity": "sha512-5aPpe5XQPzflQrFwL1/QoeHkP2MsA4JCntcXHRhEsdsfPVkvPi2w7Qix4iV7t5S/oC9OodGrggd8aco1g3SZFg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.12.11", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + } + } + }, + "@eslint/eslintrc": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.0.tgz", + "integrity": "sha512-2ZPCc+uNbjV5ERJr+aKSPRwZgKd2z11x0EgLvb1PURmUrn9QNRXFqje0Ldq454PfAVyaJYyrDvvIKSFP4NnBog==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^12.1.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "globals": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "dev": true, + "requires": { + "type-fest": "^0.8.1" + } + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + } + } + }, + "@nodelib/fs.scandir": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz", + "integrity": "sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.4", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz", + "integrity": "sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz", + "integrity": "sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.4", + "fastq": "^1.6.0" + } + }, + "@pixi/accessibility": { + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/@pixi/accessibility/-/accessibility-5.3.8.tgz", + "integrity": "sha512-DBkUUPIDfaw1hXFLTOsmZ401JSyu286rS2UB79ClxvVtDfGI7pR+Hgq1PuNeoQSiO9Db32W4grvuxYTulO2jkQ==", + "requires": { + "@pixi/core": "5.3.8", + "@pixi/display": "5.3.8", + "@pixi/utils": "5.3.8" + } + }, + "@pixi/app": { + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/@pixi/app/-/app-5.3.8.tgz", + "integrity": "sha512-eekP/tIPlERZOiWOCVKgOCc66JoAHDP7yT9DBw2LtCKswvP83iwN0PX5YR/u6Z05kUW5y8t4bigfLqEqc4uChw==", + "requires": { + "@pixi/core": "5.3.8", + "@pixi/display": "5.3.8" + } + }, + "@pixi/constants": { + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/@pixi/constants/-/constants-5.3.8.tgz", + "integrity": "sha512-vTkgBgiox2pLj2ZK/X37O6rFjsLic6CYa+rSCCMo8lCwipG/dgizYoAVIsmZy30tFgg1xYzI6qOw3MSVXupp8Q==" + }, + "@pixi/core": { + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/@pixi/core/-/core-5.3.8.tgz", + "integrity": "sha512-mbl7//UbNaIZJbS8R8g5o6cHAMW7xaJWW/dNazSJ9057Fpq5g3e3E2rreNTEILfC29cxm2sXDmgK5a9agoqJaA==", + "requires": { + "@pixi/constants": "5.3.8", + "@pixi/math": "5.3.8", + "@pixi/runner": "5.3.8", + "@pixi/settings": "5.3.8", + "@pixi/ticker": "5.3.8", + "@pixi/utils": "5.3.8" + } + }, + "@pixi/display": { + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/@pixi/display/-/display-5.3.8.tgz", + "integrity": "sha512-ch7g63ox3iow/NEGbrArLfUMJVLVF+FpdFAp72uEweIzlcyzOQV6AcQTHtiRy4+tM6LdlcLSJXJISqGKt2R0Dg==", + "requires": { + "@pixi/math": "5.3.8", + "@pixi/settings": "5.3.8", + "@pixi/utils": "5.3.8" + } + }, + "@pixi/extract": { + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/@pixi/extract/-/extract-5.3.8.tgz", + "integrity": "sha512-z09D+5qmGQilbBXhR3xlZCixkTb6+1bSo6jGsbQxpu3xaF0ogh1HB76SJ2Wi1vwba9Q/PMb6RlawdEAg+sRFMg==", + "requires": { + "@pixi/core": "5.3.8", + "@pixi/math": "5.3.8", + "@pixi/utils": "5.3.8" + } + }, + "@pixi/filter-adjustment": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@pixi/filter-adjustment/-/filter-adjustment-3.1.1.tgz", + "integrity": "sha512-N+qbkofBn5tiGn2Ubg52AEoPOM69VIO5TEHsBtm5oh2S4m/rb6FnnqPji/FzwK89iLvtYmJdbwWAYi87PWnE3Q==" + }, + "@pixi/filter-alpha": { + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/@pixi/filter-alpha/-/filter-alpha-5.3.8.tgz", + "integrity": "sha512-4vOmuWDLBiMbdQ2S3PmxzrzpPOrlzZVZ8iPEkQrBCYZ4dIuZY7NaV+9tneIK66dDfVI6OA8Ai304LH22nhC81Q==", + "requires": { + "@pixi/core": "5.3.8" + } + }, + "@pixi/filter-blur": { + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/@pixi/filter-blur/-/filter-blur-5.3.8.tgz", + "integrity": "sha512-biNqbfFIDbvOJJ+NiE9G0XojnuMQqtbcaDIiOScRoY3o3yCMjjcUxUMYrZ4xnTGGtEH23OKGUTZVf53qTQ4wiw==", + "requires": { + "@pixi/core": "5.3.8", + "@pixi/settings": "5.3.8" + } + }, + "@pixi/filter-color-matrix": { + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/@pixi/filter-color-matrix/-/filter-color-matrix-5.3.8.tgz", + "integrity": "sha512-0Ag08uPKVoHWQSAIhS27Bs/b50NVMZ+3fUdNg9jgyrRthD/Uc2ljfkIJRa95Mj31YJBS15Giu4BGfefpe1i3zw==", + "requires": { + "@pixi/core": "5.3.8" + } + }, + "@pixi/filter-displacement": { + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/@pixi/filter-displacement/-/filter-displacement-5.3.8.tgz", + "integrity": "sha512-OQYBK3oOId8VZV7KRYYdt196EYsG0cjAmQQT7P3/IETLIP6Mba+Bd/GtyxGEIBHcb7R5DebuvN4sVQtNgkRKlw==", + "requires": { + "@pixi/core": "5.3.8", + "@pixi/math": "5.3.8" + } + }, + "@pixi/filter-fxaa": { + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/@pixi/filter-fxaa/-/filter-fxaa-5.3.8.tgz", + "integrity": "sha512-eOfrp46AEjkAM1U+6k9Ga/5ezEwr1+7yGS3VijZBHntZTYKFhmGGOXrQxxL4KuslrfTV/smAflEr22U+A2H98A==", + "requires": { + "@pixi/core": "5.3.8" + } + }, + "@pixi/filter-noise": { + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/@pixi/filter-noise/-/filter-noise-5.3.8.tgz", + "integrity": "sha512-+MOz3GpB9XpH7d0B/HAz8zOp164UMKnE64Q9QI094X4KjXWj24RKZea8xFcOaOy9xKi57qqyo+3pLwqFB8ffsw==", + "requires": { + "@pixi/core": "5.3.8" + } + }, + "@pixi/graphics": { + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/@pixi/graphics/-/graphics-5.3.8.tgz", + "integrity": "sha512-auqwS6ZnDlNoerddLCoMpEzgq0o09WHH7XxwfTK75hJwBaFX1RO/nasfvCx2wAtWZxAYCaABfR8WnWZfrsBSqA==", + "requires": { + "@pixi/constants": "5.3.8", + "@pixi/core": "5.3.8", + "@pixi/display": "5.3.8", + "@pixi/math": "5.3.8", + "@pixi/sprite": "5.3.8", + "@pixi/utils": "5.3.8" + } + }, + "@pixi/interaction": { + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/@pixi/interaction/-/interaction-5.3.8.tgz", + "integrity": "sha512-i9KS9TNVK/PEwyjZH2iqui9xroy0R48u/QL4Q8+VQpwbeDlz+WlPWoW5R7rpUwtHd9H6mLWpGR3sdWOmS7fMsA==", + "requires": { + "@pixi/core": "5.3.8", + "@pixi/display": "5.3.8", + "@pixi/math": "5.3.8", + "@pixi/ticker": "5.3.8", + "@pixi/utils": "5.3.8" + } + }, + "@pixi/loaders": { + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/@pixi/loaders/-/loaders-5.3.8.tgz", + "integrity": "sha512-0M2e/gkBBqJW695wz9DcsYN7IY992FKqb9uOEhFFjCn2bkK9WsR6M/JBvTlTk4LOvEg81b1/J51bkucpXWx1Cg==", + "requires": { + "@pixi/core": "5.3.8", + "@pixi/utils": "5.3.8", + "resource-loader": "^3.0.1" + } + }, + "@pixi/math": { + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/@pixi/math/-/math-5.3.8.tgz", + "integrity": "sha512-MZekzC9W391KU2NyzbRHrgYfjPKguzU5cRLbaEw9dgDabLh3/Yzob1KVg8dngIITPbi5yBmoX7zh7ZHEA1NRPQ==" + }, + "@pixi/mesh": { + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/@pixi/mesh/-/mesh-5.3.8.tgz", + "integrity": "sha512-/CQdTypiLgSZqKx9z89cJlLQ8/FaUrc8M3HjmL8Vy5F320ERCR1YLDc6gOzyohK71wDxkUud5VbNz5woQVSBxw==", + "requires": { + "@pixi/constants": "5.3.8", + "@pixi/core": "5.3.8", + "@pixi/display": "5.3.8", + "@pixi/math": "5.3.8", + "@pixi/settings": "5.3.8", + "@pixi/utils": "5.3.8" + } + }, + "@pixi/mesh-extras": { + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/@pixi/mesh-extras/-/mesh-extras-5.3.8.tgz", + "integrity": "sha512-+lHcmvslKsmlixiJW87/t5diRy7p+tvqQbXMG4/3Vzv3dBEGq453hMIknlLr2xLGyzBtboCHObzwKfeE4tvHTw==", + "requires": { + "@pixi/constants": "5.3.8", + "@pixi/core": "5.3.8", + "@pixi/math": "5.3.8", + "@pixi/mesh": "5.3.8", + "@pixi/utils": "5.3.8" + } + }, + "@pixi/mixin-cache-as-bitmap": { + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/@pixi/mixin-cache-as-bitmap/-/mixin-cache-as-bitmap-5.3.8.tgz", + "integrity": "sha512-Y4z3yvMldRUU99I+FBOl+j+TCq7CXN2ysNED/vMD2YpfilS2/8dQcAqRNEOBXCdSixd6+QHBuc0+PWR6M7irKg==", + "requires": { + "@pixi/core": "5.3.8", + "@pixi/display": "5.3.8", + "@pixi/math": "5.3.8", + "@pixi/settings": "5.3.8", + "@pixi/sprite": "5.3.8", + "@pixi/utils": "5.3.8" + } + }, + "@pixi/mixin-get-child-by-name": { + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/@pixi/mixin-get-child-by-name/-/mixin-get-child-by-name-5.3.8.tgz", + "integrity": "sha512-6Z4C2SucwC1w2xa260VxU+uIkP8FhwnZWDfY0rxyxecWxvkM7ULsIU9szoUYUJvLJnpxRi4Xb6rXNPxXyzis9Q==", + "requires": { + "@pixi/display": "5.3.8" + } + }, + "@pixi/mixin-get-global-position": { + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/@pixi/mixin-get-global-position/-/mixin-get-global-position-5.3.8.tgz", + "integrity": "sha512-o2ZKmTxDvoibGBZ8LP3qJZ3cHe7L447qsuHPPLYOPmA5hqG49YchwmKMwV6tn96C8yDECaVn429Hu5hZEI7UlA==", + "requires": { + "@pixi/display": "5.3.8", + "@pixi/math": "5.3.8" + } + }, + "@pixi/particles": { + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/@pixi/particles/-/particles-5.3.8.tgz", + "integrity": "sha512-XAehJJ9SsLwlZF1Qkkir0ejPZ0YgCg8MbxzmrxBUbhH1NyHJLFm+K2S7Bp12FdR/hZwTENF7GMGVRH+o86u3hw==", + "requires": { + "@pixi/constants": "5.3.8", + "@pixi/core": "5.3.8", + "@pixi/display": "5.3.8", + "@pixi/math": "5.3.8", + "@pixi/utils": "5.3.8" + } + }, + "@pixi/polyfill": { + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/@pixi/polyfill/-/polyfill-5.3.8.tgz", + "integrity": "sha512-AIXfAjYD7dfP2C+TX3482YterwGE876amqmk6EzMZCI3vvsvDJUGT/Dx6lSOU5zbcUbJ9t3Ybz81xQYpaEhv/Q==", + "requires": { + "es6-promise-polyfill": "^1.2.0", + "object-assign": "^4.1.1" + } + }, + "@pixi/prepare": { + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/@pixi/prepare/-/prepare-5.3.8.tgz", + "integrity": "sha512-DbYxQdziypsdQJaRKwdmODkIy2mQHETEFlVWou0XwVy+WB8VBlSnHZ57cVEY8l6Z0hJ93Vo4K6j5qIRi9MRjJA==", + "requires": { + "@pixi/core": "5.3.8", + "@pixi/display": "5.3.8", + "@pixi/graphics": "5.3.8", + "@pixi/settings": "5.3.8", + "@pixi/text": "5.3.8", + "@pixi/ticker": "5.3.8" + } + }, + "@pixi/runner": { + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/@pixi/runner/-/runner-5.3.8.tgz", + "integrity": "sha512-6Y9v9OHd5FFv6s0M4AGHnG3qvLiTBM5T5RnlEqMNMsqH6CWSDq0mNJA5HQD65q5ViK8HM6MYPm2nwwkYq5AICQ==" + }, + "@pixi/settings": { + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/@pixi/settings/-/settings-5.3.8.tgz", + "integrity": "sha512-/NSd9v6+IbG3GjzIoNwy7rgPg6kwwWy54pcaiM3Wv3zjkwhkVySK4m3h892Wa2z5lFvrHEH9zewGJwEpUH/FMA==", + "requires": { + "ismobilejs": "^1.1.0" + } + }, + "@pixi/sprite": { + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/@pixi/sprite/-/sprite-5.3.8.tgz", + "integrity": "sha512-r+WeX5cti3VKu6U+hZeSiY4UC8912FjNU7M5bA/gev9CfUKv3fNwKYshPfzOkTPua8dFwI1U6tplYu5rSPMBmw==", + "requires": { + "@pixi/constants": "5.3.8", + "@pixi/core": "5.3.8", + "@pixi/display": "5.3.8", + "@pixi/math": "5.3.8", + "@pixi/settings": "5.3.8", + "@pixi/utils": "5.3.8" + } + }, + "@pixi/sprite-animated": { + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/@pixi/sprite-animated/-/sprite-animated-5.3.8.tgz", + "integrity": "sha512-zLnzmCJJ++Hyyy1LPh5Lt4icPuy8C+vL59yVj3nAYzqq/G26rFuHELexB0iwKBPE9yQYuaUQhFgOPgW4vFqLAw==", + "requires": { + "@pixi/core": "5.3.8", + "@pixi/sprite": "5.3.8", + "@pixi/ticker": "5.3.8" + } + }, + "@pixi/sprite-tiling": { + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/@pixi/sprite-tiling/-/sprite-tiling-5.3.8.tgz", + "integrity": "sha512-SvCAvajihsaNx/xX4s6waEqPLVkI5W86h31kpoqdPj3zXhoLbpZh6t2TWbcRJmgjM1GvBNy14gWtelBq8UF7Mg==", + "requires": { + "@pixi/constants": "5.3.8", + "@pixi/core": "5.3.8", + "@pixi/display": "5.3.8", + "@pixi/math": "5.3.8", + "@pixi/sprite": "5.3.8", + "@pixi/utils": "5.3.8" + } + }, + "@pixi/spritesheet": { + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/@pixi/spritesheet/-/spritesheet-5.3.8.tgz", + "integrity": "sha512-KqTsW2LViI1UjZTycfI0x3m+yZqV8zfIm/CiDAmtujUPAu8sU78jzByc8ke7FaFC6waDsfAKTKu4fBqSu7aH1w==", + "requires": { + "@pixi/core": "5.3.8", + "@pixi/loaders": "5.3.8", + "@pixi/math": "5.3.8", + "@pixi/utils": "5.3.8" + } + }, + "@pixi/text": { + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/@pixi/text/-/text-5.3.8.tgz", + "integrity": "sha512-qarv4kXSrtroJy5dbmF0Vld7L8teeQxsV5N1g1Fjhi4uUCb43ioR9euBHIjju33kOLDYYXXw6L78XIe/cW6nIw==", + "requires": { + "@pixi/core": "5.3.8", + "@pixi/math": "5.3.8", + "@pixi/settings": "5.3.8", + "@pixi/sprite": "5.3.8", + "@pixi/utils": "5.3.8" + } + }, + "@pixi/text-bitmap": { + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/@pixi/text-bitmap/-/text-bitmap-5.3.8.tgz", + "integrity": "sha512-jJVAc/y7Mo/DLw8n14A1AFmhQe8rw5d+vCg/1k4hw0Oru4l2QU/8AA940kPeuky4Sj0hMLf9UWAS6A3gOo5ZTA==", + "requires": { + "@pixi/core": "5.3.8", + "@pixi/display": "5.3.8", + "@pixi/loaders": "5.3.8", + "@pixi/math": "5.3.8", + "@pixi/mesh": "5.3.8", + "@pixi/settings": "5.3.8", + "@pixi/text": "5.3.8", + "@pixi/utils": "5.3.8" + } + }, + "@pixi/ticker": { + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/@pixi/ticker/-/ticker-5.3.8.tgz", + "integrity": "sha512-WoVi8btR0X2/fXJgt/oRy2gm32ECnibqUkxl0MOcLuxg7cHDZKFA5PwNK/eIx5hZZ2xM/ztoPtEohWV6LqLryw==", + "requires": { + "@pixi/settings": "5.3.8" + } + }, + "@pixi/utils": { + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/@pixi/utils/-/utils-5.3.8.tgz", + "integrity": "sha512-LljIFFOFcXLyLzXqIYwcXUqz6NsAUbwxb7Som9Gm3i1usGIqPRX4R08Iaf4L6OKA7417gSrRmbYdT0Hje/0ikA==", + "requires": { + "@pixi/constants": "5.3.8", + "@pixi/settings": "5.3.8", + "earcut": "^2.1.5", + "eventemitter3": "^3.1.0", + "url": "^0.11.0" + } + }, + "@types/json-schema": { + "version": "7.0.7", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", + "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==", + "dev": true + }, + "@types/node": { + "version": "14.14.35", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.35.tgz", + "integrity": "sha512-Lt+wj8NVPx0zUmUwumiVXapmaLUcAk3yPuHCFVXras9k5VT9TdhJqKqGVUQCD60OTMCl0qxJ57OiTL0Mic3Iag==", + "dev": true + }, + "@types/pako": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/pako/-/pako-1.0.1.tgz", + "integrity": "sha512-GdZbRSJ3Cv5fiwT6I0SQ3ckeN2PWNqxd26W9Z2fCK1tGrrasGy4puvNFtnddqH9UJFMQYXxEuuB7B8UK+LLwSg==", + "dev": true + }, + "@typescript-eslint/eslint-plugin": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.18.0.tgz", + "integrity": "sha512-Lzkc/2+7EoH7+NjIWLS2lVuKKqbEmJhtXe3rmfA8cyiKnZm3IfLf51irnBcmow8Q/AptVV0XBZmBJKuUJTe6cQ==", + "dev": true, + "requires": { + "@typescript-eslint/experimental-utils": "4.18.0", + "@typescript-eslint/scope-manager": "4.18.0", + "debug": "^4.1.1", + "functional-red-black-tree": "^1.0.1", + "lodash": "^4.17.15", + "regexpp": "^3.0.0", + "semver": "^7.3.2", + "tsutils": "^3.17.1" + } + }, + "@typescript-eslint/experimental-utils": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.18.0.tgz", + "integrity": "sha512-92h723Kblt9JcT2RRY3QS2xefFKar4ZQFVs3GityOKWQYgtajxt/tuXIzL7sVCUlM1hgreiV5gkGYyBpdOwO6A==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.3", + "@typescript-eslint/scope-manager": "4.18.0", + "@typescript-eslint/types": "4.18.0", + "@typescript-eslint/typescript-estree": "4.18.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^2.0.0" + } + }, + "@typescript-eslint/parser": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.18.0.tgz", + "integrity": "sha512-W3z5S0ZbecwX3PhJEAnq4mnjK5JJXvXUDBYIYGoweCyWyuvAKfGHvzmpUzgB5L4cRBb+cTu9U/ro66dx7dIimA==", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "4.18.0", + "@typescript-eslint/types": "4.18.0", + "@typescript-eslint/typescript-estree": "4.18.0", + "debug": "^4.1.1" + } + }, + "@typescript-eslint/scope-manager": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.18.0.tgz", + "integrity": "sha512-olX4yN6rvHR2eyFOcb6E4vmhDPsfdMyfQ3qR+oQNkAv8emKKlfxTWUXU5Mqxs2Fwe3Pf1BoPvrwZtwngxDzYzQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.18.0", + "@typescript-eslint/visitor-keys": "4.18.0" + } + }, + "@typescript-eslint/types": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.18.0.tgz", + "integrity": "sha512-/BRociARpj5E+9yQ7cwCF/SNOWwXJ3qhjurMuK2hIFUbr9vTuDeu476Zpu+ptxY2kSxUHDGLLKy+qGq2sOg37A==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.18.0.tgz", + "integrity": "sha512-wt4xvF6vvJI7epz+rEqxmoNQ4ZADArGQO9gDU+cM0U5fdVv7N+IAuVoVAoZSOZxzGHBfvE3XQMLdy+scsqFfeg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.18.0", + "@typescript-eslint/visitor-keys": "4.18.0", + "debug": "^4.1.1", + "globby": "^11.0.1", + "is-glob": "^4.0.1", + "semver": "^7.3.2", + "tsutils": "^3.17.1" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.18.0.tgz", + "integrity": "sha512-Q9t90JCvfYaN0OfFUgaLqByOfz8yPeTAdotn/XYNm5q9eHax90gzdb+RJ6E9T5s97Kv/UHWKERTmqA0jTKAEHw==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.18.0", + "eslint-visitor-keys": "^2.0.0" + } + }, + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true + }, + "acorn-jsx": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", + "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", + "dev": true + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, + "astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "earcut": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/earcut/-/earcut-2.2.2.tgz", + "integrity": "sha512-eZoZPPJcUHnfRZ0PjLvx2qBordSiO8ofC3vt+qACLM95u+4DovnbYNpQtJh0DNsWj8RnxrQytD4WA8gj5cRIaQ==" + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "requires": { + "ansi-colors": "^4.1.1" + } + }, + "es6-promise-polyfill": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/es6-promise-polyfill/-/es6-promise-polyfill-1.2.0.tgz", + "integrity": "sha1-84kl8jyz4+jObNqP93T867sJDN4=" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "eslint": { + "version": "7.22.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.22.0.tgz", + "integrity": "sha512-3VawOtjSJUQiiqac8MQc+w457iGLfuNGLFn8JmF051tTKbh5/x/0vlcEj8OgDCaw7Ysa2Jn8paGshV7x2abKXg==", + "dev": true, + "requires": { + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.0", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.0.0", + "globals": "^13.6.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash": "^4.17.21", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^6.0.4", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "dependencies": { + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + } + } + }, + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } + } + }, + "eslint-visitor-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz", + "integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==", + "dev": true + }, + "espree": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "dev": true, + "requires": { + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^1.3.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "eventemitter3": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", + "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==" + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-glob": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz", + "integrity": "sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.0", + "merge2": "^1.3.0", + "micromatch": "^4.0.2", + "picomatch": "^2.2.1" + } + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "fastq": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.0.tgz", + "integrity": "sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, + "file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "requires": { + "flat-cache": "^3.0.4" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "requires": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + } + }, + "flatted": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz", + "integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "globals": { + "version": "13.6.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.6.0.tgz", + "integrity": "sha512-YFKCX0SiPg7l5oKYCJ2zZGxcXprVXHcSnVuvzrT3oSENQonVLqM5pf9fN5dLGZGyCjhw8TN8Btwe/jKnZ0pjvQ==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + }, + "dependencies": { + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + } + } + }, + "globby": { + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.2.tgz", + "integrity": "sha512-2ZThXDvvV8fYFRVIxnrMQBipZQDr7MxKAmQK1vujaj9/7eF0efG7BPUKJ7jP7G5SLF37xKDXvO4S/KKLj/Z0og==", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "ismobilejs": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ismobilejs/-/ismobilejs-1.1.1.tgz", + "integrity": "sha512-VaFW53yt8QO61k2WJui0dHf4SlL8lxBofUuUmwBo0ljPk0Drz2TiuDW4jo3wDcv41qy/SxrJ+VAzJ/qYqsmzRw==" + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "mini-signals": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mini-signals/-/mini-signals-1.2.0.tgz", + "integrity": "sha1-RbCAE8X65RokqhqTXNMXye1yHXQ=" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, + "pako": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pako/-/pako-2.0.3.tgz", + "integrity": "sha512-WjR1hOeg+kki3ZIOjaf4b5WVcay1jaliKSYiEaB1XzwhMQZJxRdQRv0V31EKBYlxb4T7SK3hjfc/jxyU64BoSw==" + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "parse-uri": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/parse-uri/-/parse-uri-1.0.3.tgz", + "integrity": "sha512-upMnGxNcm+45So85HoguwZTVZI9u11i36DdxJfGF2HYWS2eh3TIx7+/tTi7qrEq15qzGkVhsKjesau+kCk48pA==" + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + }, + "picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "dev": true + }, + "pixi.js": { + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/pixi.js/-/pixi.js-5.3.8.tgz", + "integrity": "sha512-kDqkWhuAkc42lD+ldVTaS439q7D7uo9FM/wCP26jUNAFlYAp75IcALEgXuBh6HEjp51enGkRvwX9+fIiA5F9ug==", + "requires": { + "@pixi/accessibility": "5.3.8", + "@pixi/app": "5.3.8", + "@pixi/constants": "5.3.8", + "@pixi/core": "5.3.8", + "@pixi/display": "5.3.8", + "@pixi/extract": "5.3.8", + "@pixi/filter-alpha": "5.3.8", + "@pixi/filter-blur": "5.3.8", + "@pixi/filter-color-matrix": "5.3.8", + "@pixi/filter-displacement": "5.3.8", + "@pixi/filter-fxaa": "5.3.8", + "@pixi/filter-noise": "5.3.8", + "@pixi/graphics": "5.3.8", + "@pixi/interaction": "5.3.8", + "@pixi/loaders": "5.3.8", + "@pixi/math": "5.3.8", + "@pixi/mesh": "5.3.8", + "@pixi/mesh-extras": "5.3.8", + "@pixi/mixin-cache-as-bitmap": "5.3.8", + "@pixi/mixin-get-child-by-name": "5.3.8", + "@pixi/mixin-get-global-position": "5.3.8", + "@pixi/particles": "5.3.8", + "@pixi/polyfill": "5.3.8", + "@pixi/prepare": "5.3.8", + "@pixi/runner": "5.3.8", + "@pixi/settings": "5.3.8", + "@pixi/sprite": "5.3.8", + "@pixi/sprite-animated": "5.3.8", + "@pixi/sprite-tiling": "5.3.8", + "@pixi/spritesheet": "5.3.8", + "@pixi/text": "5.3.8", + "@pixi/text-bitmap": "5.3.8", + "@pixi/ticker": "5.3.8", + "@pixi/utils": "5.3.8" + } + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" + }, + "queue-microtask": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.2.tgz", + "integrity": "sha512-dB15eXv3p2jDlbOiNLyMabYg1/sXvppd8DP2J3EOCQ0AkuSXCW2tP7mnVouVLJKgUMY6yP0kcQDVpLCN13h4Xg==", + "dev": true + }, + "regexpp": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", + "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", + "dev": true + }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, + "resource-loader": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/resource-loader/-/resource-loader-3.0.1.tgz", + "integrity": "sha512-fBuCRbEHdLCI1eglzQhUv9Rrdcmqkydr1r6uHE2cYHvRBrcLXeSmbE/qI/urFt8rPr/IGxir3BUwM5kUK8XoyA==", + "requires": { + "mini-signals": "^1.2.0", + "parse-uri": "^1.0.0" + } + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "requires": { + "queue-microtask": "^1.2.2" + } + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, + "semver": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + } + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "table": { + "version": "6.0.7", + "resolved": "https://registry.npmjs.org/table/-/table-6.0.7.tgz", + "integrity": "sha512-rxZevLGTUzWna/qBLObOe16kB2RTnnbhciwgPbMMlazz1yZGVEgnZK762xyVdVznhqxrfCeBMmMkgOOaPwjH7g==", + "dev": true, + "requires": { + "ajv": "^7.0.2", + "lodash": "^4.17.20", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.0" + }, + "dependencies": { + "ajv": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-7.2.1.tgz", + "integrity": "sha512-+nu0HDv7kNSOua9apAVc979qd932rrZeb3WOvoiD31A/p1mIE5/9bN2027pE2rOPYEdS3UHzsvof4hY+lM9/WQ==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + } + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "tslib": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz", + "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==" + }, + "tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + } + } + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + }, + "typescript": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.3.tgz", + "integrity": "sha512-qOcYwxaByStAWrBf4x0fibwZvMRG+r4cQoTjbPtUlrWjBHbmCAww1i448U0GJ+3cNNEtebDteo/cHOR3xJ4wEw==", + "dev": true + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + } + } + }, + "url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + } + }, + "v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "xml2js": { + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", + "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", + "requires": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + } + }, + "xmlbuilder": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==" + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 00000000..476a1d60 --- /dev/null +++ b/package.json @@ -0,0 +1,23 @@ +{ + "name": "nitro-renderer", + "version": "1.0.0", + "scripts": { + "eslint": "eslint ./src --fix" + }, + "private": true, + "dependencies": { + "@pixi/filter-adjustment": "^3.1.1", + "pako": "^2.0.3", + "pixi.js": "^5.3.3", + "tslib": "^2.0.0", + "xml2js": "^0.4.23" + }, + "devDependencies": { + "@types/node": "^14.14.35", + "@types/pako": "^1.0.1", + "@typescript-eslint/eslint-plugin": "^4.15.0", + "@typescript-eslint/parser": "^4.15.0", + "eslint": "^7.19.0", + "typescript": "~4.2.3" + } +} diff --git a/src/core/INitroCore.ts b/src/core/INitroCore.ts new file mode 100644 index 00000000..a3f6da74 --- /dev/null +++ b/src/core/INitroCore.ts @@ -0,0 +1,11 @@ +import { IAssetManager } from './asset/IAssetManager'; +import { IDisposable } from './common/disposable/IDisposable'; +import { ICommunicationManager } from './communication/ICommunicationManager'; +import { IConfigurationManager } from './configuration/IConfigurationManager'; + +export interface INitroCore extends IDisposable +{ + configuration: IConfigurationManager; + asset: IAssetManager; + communication: ICommunicationManager; +} \ No newline at end of file diff --git a/src/core/NitroCore.ts b/src/core/NitroCore.ts new file mode 100644 index 00000000..d7a44636 --- /dev/null +++ b/src/core/NitroCore.ts @@ -0,0 +1,60 @@ +import { AssetManager } from './asset/AssetManager'; +import { IAssetManager } from './asset/IAssetManager'; +import { Disposable } from './common/disposable/Disposable'; +import { CommunicationManager } from './communication/CommunicationManager'; +import { ICommunicationManager } from './communication/ICommunicationManager'; +import { ConfigurationManager } from './configuration/ConfigurationManager'; +import { IConfigurationManager } from './configuration/IConfigurationManager'; +import { INitroCore } from './INitroCore'; + +export class NitroCore extends Disposable implements INitroCore +{ + private _configuration: IConfigurationManager; + private _communication: ICommunicationManager; + private _asset: IAssetManager; + + constructor() + { + super(); + + window.console.log.apply(console, [ + '\n%c _ ___ __ \n / | / (_) /__________ \n / |/ / / __/ ___/ __ \\ \n / /| / / /_/ / / /_/ / \n /_/ |_/_/\\__/_/ \\____/ \n \n Thanks for using Nitro \n To report bugs or issues \n join us on Discord \n https://discord.gg/66UR68FPgy \n \n', + 'color: #FFFFFF; background: #000000; padding:0px 0;' ]); + + this._configuration = new ConfigurationManager(); + this._communication = new CommunicationManager(); + this._asset = new AssetManager(); + } + + protected onDispose(): void + { + if(this._asset) + { + this._asset.dispose(); + + this._asset = null; + } + + if(this._communication) + { + this._communication.dispose(); + + this._communication = null; + } + } + + public get configuration(): IConfigurationManager + { + return this._configuration; + } + + public get communication(): ICommunicationManager + { + return this._communication; + } + + public get asset(): IAssetManager + { + return this._asset; + } +} \ No newline at end of file diff --git a/src/core/asset/AssetManager.ts b/src/core/asset/AssetManager.ts new file mode 100644 index 00000000..8b0ec9cb --- /dev/null +++ b/src/core/asset/AssetManager.ts @@ -0,0 +1,319 @@ +import { BaseTexture, ILoaderOptions, Loader, LoaderResource, Spritesheet, Texture } from 'pixi.js'; +import { GraphicAssetCollection } from '../../room/object/visualization/utils/GraphicAssetCollection'; +import { IGraphicAsset } from '../../room/object/visualization/utils/IGraphicAsset'; +import { IGraphicAssetCollection } from '../../room/object/visualization/utils/IGraphicAssetCollection'; +import { Disposable } from '../common/disposable/Disposable'; +import { INitroLogger } from '../common/logger/INitroLogger'; +import { NitroLogger } from '../common/logger/NitroLogger'; +import { IAssetManager } from './IAssetManager'; +import { IAssetData } from './interfaces'; +import { NitroBundle } from './NitroBundle'; + +export class AssetManager extends Disposable implements IAssetManager +{ + private _logger: INitroLogger; + private _textures: Map; + private _collections: Map; + private _pendingUrls: Map; + + constructor() + { + super(); + + this._logger = new NitroLogger(this.constructor.name); + this._textures = new Map(); + this._collections = new Map(); + this._pendingUrls = new Map(); + } + + public static removeFileExtension(name: string): string + { + return (name.substring(0, name.lastIndexOf('.')) || name); + } + + public getTexture(name: string): Texture + { + if(!name) return null; + + const existing = this._textures.get(name); + + if(!existing) return null; + + return existing; + } + + public setTexture(name: string, texture: Texture): void + { + if(!name || !texture) return; + + this._textures.set(name, texture); + } + + public getAsset(name: string): IGraphicAsset + { + if(!name) return null; + + for(const collection of this._collections.values()) + { + if(!collection) continue; + + const existing = collection.getAsset(name); + + if(!existing) continue; + + return existing; + } + + return null; + } + + public getCollection(name: string): IGraphicAssetCollection + { + if(!name) return null; + + const existing = this._collections.get(name); + + if(!existing) return null; + + return existing; + } + + public createCollection(data: IAssetData, spritesheet: Spritesheet): IGraphicAssetCollection + { + if(!data) return null; + + const collection = new GraphicAssetCollection(data, spritesheet); + + if(collection) + { + for(const [ name, texture ] of collection.textures.entries()) this.setTexture(name, texture); + + this._collections.set(collection.name, collection); + } + } + + public downloadAsset(assetUrl: string, cb: Function): boolean + { + return this.downloadAssets([ assetUrl ], cb); + } + + public downloadAssets(assetUrls: string[], cb: Function): boolean + { + if(!assetUrls || !assetUrls.length) + { + cb(true); + + return true; + } + + const totalToDownload = assetUrls.length; + + let totalDownloaded = 0; + + const onDownloaded = (loader: Loader, resource: LoaderResource, flag: boolean) => + { + if(loader) loader.destroy(); + + if(!flag) + { + this._logger.error('Failed to download asset: ' + resource.url); + + cb(false); + + return; + } + + totalDownloaded++; + + if(totalDownloaded === totalToDownload) cb(true); + }; + + for(const url of assetUrls) + { + if(!url) continue; + + const loader = new Loader(); + + const options: ILoaderOptions = { + crossOrigin: false, + xhrType: url.endsWith('.nitro') ? 'arraybuffer' : 'json' + }; + + loader + .use((resource: LoaderResource, next: Function) => this.assetLoader(loader, resource, next, onDownloaded)) + .add(url, options) + .load(); + } + + return true; + } + + private assetLoader(loader: Loader, resource: LoaderResource, next: Function, onDownloaded: Function): void + { + if(!resource || resource.error) + { + if(resource && resource.texture) resource.texture.destroy(true); + + onDownloaded(loader, resource, false); + + return; + } + + if(resource.extension === 'nitro') + { + const nitroBundle = new NitroBundle(resource.data); + const assetData = (nitroBundle.jsonFile as IAssetData); + + if(!assetData || !assetData.type) + { + onDownloaded(loader, resource, false); + + return; + } + + if(assetData.spritesheet && Object.keys(assetData.spritesheet).length) + { + const baseTexture = nitroBundle.baseTexture; + + if(!baseTexture) + { + onDownloaded(loader, resource, false); + + return; + } + + if(baseTexture.valid) + { + const spritesheet = new Spritesheet(baseTexture, assetData.spritesheet); + + spritesheet.parse(textures => + { + this.createCollection(assetData, spritesheet); + + onDownloaded(loader, resource, true); + }); + } + else + { + baseTexture.once('loaded', () => + { + baseTexture.removeAllListeners(); + + const spritesheet = new Spritesheet(baseTexture, assetData.spritesheet); + + spritesheet.parse(textures => + { + this.createCollection(assetData, spritesheet); + + onDownloaded(loader, resource, true); + }); + }); + + baseTexture.once('error', () => + { + baseTexture.removeAllListeners(); + + onDownloaded(loader, resource, false); + }); + } + + return; + } + + this.createCollection(assetData, null); + + onDownloaded(loader, resource, true); + } + + else if(resource.type === LoaderResource.TYPE.JSON) + { + const assetData = (resource.data as IAssetData); + + if(!assetData || !assetData.type) + { + onDownloaded(loader, resource, false); + + return; + } + + if(assetData.spritesheet && Object.keys(assetData.spritesheet).length) + { + const imageName = (assetData.spritesheet.meta && assetData.spritesheet.meta.image); + + if(!imageName || !imageName.length) + { + onDownloaded(loader, resource, false); + + return; + } + + const imageUrl = (resource.url.substring(0, (resource.url.lastIndexOf('/') + 1)) + imageName); + const baseTexture = BaseTexture.from(imageUrl); + + if(baseTexture.valid) + { + const spritesheet = new Spritesheet(baseTexture, assetData.spritesheet); + + spritesheet.parse(textures => + { + this.createCollection(assetData, spritesheet); + + onDownloaded(loader, resource, true); + }); + } + else + { + baseTexture.once('loaded', () => + { + baseTexture.removeAllListeners(); + + const spritesheet = new Spritesheet(baseTexture, assetData.spritesheet); + + spritesheet.parse(textures => + { + this.createCollection(assetData, spritesheet); + + onDownloaded(loader, resource, true); + }); + }); + + baseTexture.once('error', () => + { + baseTexture.removeAllListeners(); + + onDownloaded(loader, resource, false); + }); + } + + return; + } + + this.createCollection(assetData, null); + + onDownloaded(loader, resource, true); + + return; + } + + if(resource.type === LoaderResource.TYPE.IMAGE) + { + if(resource.texture.valid) + { + this.setTexture(resource.name, resource.texture); + + onDownloaded(loader, resource, true); + } + else + { + onDownloaded(loader, resource, false); + } + + return; + } + } + + public get collections(): Map + { + return this._collections; + } +} diff --git a/src/core/asset/IAssetManager.ts b/src/core/asset/IAssetManager.ts new file mode 100644 index 00000000..7745c71d --- /dev/null +++ b/src/core/asset/IAssetManager.ts @@ -0,0 +1,19 @@ + +import { Spritesheet, Texture } from 'pixi.js'; +import { GraphicAssetCollection } from '../../room/object/visualization/utils/GraphicAssetCollection'; +import { IGraphicAsset } from '../../room/object/visualization/utils/IGraphicAsset'; +import { IGraphicAssetCollection } from '../../room/object/visualization/utils/IGraphicAssetCollection'; +import { IAssetData } from './interfaces'; + +export interface IAssetManager +{ + dispose(): void; + getTexture(name: string): Texture; + setTexture(name: string, texture: Texture): void; + getAsset(name: string): IGraphicAsset; + getCollection(name: string): IGraphicAssetCollection; + createCollection(data: IAssetData, spritesheet: Spritesheet): IGraphicAssetCollection; + downloadAssets(urls: string[], cb: Function): void; + downloadAsset(url: string, cb: Function): void; + collections: Map; +} \ No newline at end of file diff --git a/src/core/asset/NitroBundle.ts b/src/core/asset/NitroBundle.ts new file mode 100644 index 00000000..00837ea8 --- /dev/null +++ b/src/core/asset/NitroBundle.ts @@ -0,0 +1,71 @@ +import { Data, inflate } from 'pako'; +import { BaseTexture } from 'pixi.js'; +import { BinaryReader } from '../communication/codec/BinaryReader'; + +export class NitroBundle +{ + private static TEXT_DECODER: TextDecoder = new TextDecoder('utf-8'); + + private _jsonFile: Object = null; + private _image: string = null; + private _imageData: Uint8Array = null; + private _baseTexture: BaseTexture = null; + + constructor(arrayBuffer: ArrayBuffer) + { + this.parse(arrayBuffer); + } + + private static arrayBufferToBase64(buffer: ArrayBuffer): string + { + let binary = ''; + + const bytes = new Uint8Array(buffer); + const len = bytes.byteLength; + + for(let i = 0; i < len; i++) (binary += String.fromCharCode(bytes[i])); + + return window.btoa(binary); + } + + public parse(arrayBuffer: ArrayBuffer): void + { + const binaryReader = new BinaryReader(arrayBuffer); + + let fileCount = binaryReader.readShort(); + + while(fileCount > 0) + { + const fileNameLength = binaryReader.readShort(); + const fileName = binaryReader.readBytes(fileNameLength).toString(); + const fileLength = binaryReader.readInt(); + const buffer = binaryReader.readBytes(fileLength); + + if(fileName.endsWith('.json')) + { + const decompressed = inflate((buffer.toArrayBuffer() as Data)); + + this._jsonFile = JSON.parse(NitroBundle.TEXT_DECODER.decode(decompressed)); + } + else + { + const decompressed = inflate((buffer.toArrayBuffer() as Data)); + const base64 = NitroBundle.arrayBufferToBase64(decompressed); + + this._baseTexture = new BaseTexture('data:image/png;base64,' + base64); + } + + fileCount--; + } + } + + get jsonFile(): Object + { + return this._jsonFile; + } + + public get baseTexture(): BaseTexture + { + return this._baseTexture; + } +} diff --git a/src/core/asset/index.ts b/src/core/asset/index.ts new file mode 100644 index 00000000..a66a117d --- /dev/null +++ b/src/core/asset/index.ts @@ -0,0 +1,4 @@ +export * from './AssetManager'; +export * from './IAssetManager'; +export * from './interfaces'; +export * from './NitroBundle'; diff --git a/src/core/asset/interfaces/IAsset.ts b/src/core/asset/interfaces/IAsset.ts new file mode 100644 index 00000000..f4e4fb4d --- /dev/null +++ b/src/core/asset/interfaces/IAsset.ts @@ -0,0 +1,9 @@ +export interface IAsset +{ + source?: string; + x?: number; + y?: number; + flipH?: boolean; + flipV?: boolean; + usesPalette?: boolean; +} diff --git a/src/core/asset/interfaces/IAssetAlias.ts b/src/core/asset/interfaces/IAssetAlias.ts new file mode 100644 index 00000000..5c14027d --- /dev/null +++ b/src/core/asset/interfaces/IAssetAlias.ts @@ -0,0 +1,6 @@ +export interface IAssetAlias +{ + link?: string; + flipH?: boolean; + flipV?: boolean; +} diff --git a/src/core/asset/interfaces/IAssetData.ts b/src/core/asset/interfaces/IAssetData.ts new file mode 100644 index 00000000..2af33ca5 --- /dev/null +++ b/src/core/asset/interfaces/IAssetData.ts @@ -0,0 +1,26 @@ +import { IAssetAnimation } from './animation'; +import { IAsset } from './IAsset'; +import { IAssetAlias } from './IAssetAlias'; +import { IAssetDimension } from './IAssetDimension'; +import { IAssetPalette } from './IAssetPalette'; +import { ISpritesheetData } from './spritesheet'; +import { IAssetVisualizationData } from './visualization'; + +export interface IAssetData { + type?: string; + name?: string; + visualizationType?: string; + logicType?: string; + maskType?: string; + credits?: string; + soundSample?: number; + action?: { link?: string, startState?: number }; + spritesheet?: ISpritesheetData; + dimensions?: IAssetDimension; + directions?: number[]; + assets?: { [index: string]: IAsset }; + aliases?: { [index: string]: IAssetAlias }; + animations?: { [index: string]: IAssetAnimation }; + palettes?: { [index: string]: IAssetPalette }; + visualizations?: IAssetVisualizationData[]; +} diff --git a/src/core/asset/interfaces/IAssetDimension.ts b/src/core/asset/interfaces/IAssetDimension.ts new file mode 100644 index 00000000..4a4629fa --- /dev/null +++ b/src/core/asset/interfaces/IAssetDimension.ts @@ -0,0 +1,6 @@ +export interface IAssetDimension +{ + x: number; + y: number; + z?: number; +} \ No newline at end of file diff --git a/src/core/asset/interfaces/IAssetPalette.ts b/src/core/asset/interfaces/IAssetPalette.ts new file mode 100644 index 00000000..5102e95f --- /dev/null +++ b/src/core/asset/interfaces/IAssetPalette.ts @@ -0,0 +1,8 @@ +export interface IAssetPalette +{ + id?: number; + source?: string; + color1?: string; + color2?: string; + rgb?: [ number, number, number ][]; +} diff --git a/src/core/asset/interfaces/animation/IAssetAnimation.ts b/src/core/asset/interfaces/animation/IAssetAnimation.ts new file mode 100644 index 00000000..b35e0eb9 --- /dev/null +++ b/src/core/asset/interfaces/animation/IAssetAnimation.ts @@ -0,0 +1,23 @@ +import { IAssetAnimationAdd } from './IAssetAnimationAdd'; +import { IAssetAnimationAvatar } from './IAssetAnimationAvatar'; +import { IAssetAnimationDirection } from './IAssetAnimationDirection'; +import { IAssetAnimationFrame } from './IAssetAnimationFrame'; +import { IAssetAnimationOverride } from './IAssetAnimationOverride'; +import { IAssetAnimationRemove } from './IAssetAnimationRemove'; +import { IAssetAnimationShadow } from './IAssetAnimationShadow'; +import { IAssetAnimationSprite } from './IAssetAnimationSprite'; + +export interface IAssetAnimation +{ + name?: string; + desc?: string; + resetOnToggle?: boolean; + directions?: IAssetAnimationDirection[]; + shadows?: IAssetAnimationShadow[]; + adds?: IAssetAnimationAdd[]; + removes?: IAssetAnimationRemove[]; + sprites?: IAssetAnimationSprite[]; + frames?: IAssetAnimationFrame[]; + avatars?: IAssetAnimationAvatar[]; + overrides?: IAssetAnimationOverride[]; +} diff --git a/src/core/asset/interfaces/animation/IAssetAnimationAdd.ts b/src/core/asset/interfaces/animation/IAssetAnimationAdd.ts new file mode 100644 index 00000000..3da37c6a --- /dev/null +++ b/src/core/asset/interfaces/animation/IAssetAnimationAdd.ts @@ -0,0 +1,8 @@ +export interface IAssetAnimationAdd +{ + id?: string; + align?: string; + blend?: string; + ink?: number; + base?: string; +} diff --git a/src/core/asset/interfaces/animation/IAssetAnimationAvatar.ts b/src/core/asset/interfaces/animation/IAssetAnimationAvatar.ts new file mode 100644 index 00000000..dcd030ef --- /dev/null +++ b/src/core/asset/interfaces/animation/IAssetAnimationAvatar.ts @@ -0,0 +1,6 @@ +export interface IAssetAnimationAvatar +{ + ink?: number; + foreground?: string; + background?: string; +} diff --git a/src/core/asset/interfaces/animation/IAssetAnimationDirection.ts b/src/core/asset/interfaces/animation/IAssetAnimationDirection.ts new file mode 100644 index 00000000..0c18eaef --- /dev/null +++ b/src/core/asset/interfaces/animation/IAssetAnimationDirection.ts @@ -0,0 +1,4 @@ +export interface IAssetAnimationDirection +{ + offset?: number; +} diff --git a/src/core/asset/interfaces/animation/IAssetAnimationFrame.ts b/src/core/asset/interfaces/animation/IAssetAnimationFrame.ts new file mode 100644 index 00000000..b8b88a05 --- /dev/null +++ b/src/core/asset/interfaces/animation/IAssetAnimationFrame.ts @@ -0,0 +1,8 @@ +import { IAssetAnimationFramePart } from './IAssetAnimationFramePart'; + +export interface IAssetAnimationFrame +{ + repeats?: number; + fxs?: IAssetAnimationFramePart[]; + bodyparts?: IAssetAnimationFramePart[]; +} diff --git a/src/core/asset/interfaces/animation/IAssetAnimationFramePart.ts b/src/core/asset/interfaces/animation/IAssetAnimationFramePart.ts new file mode 100644 index 00000000..ac8c093a --- /dev/null +++ b/src/core/asset/interfaces/animation/IAssetAnimationFramePart.ts @@ -0,0 +1,14 @@ +import { IAssetAnimationFramePartItem } from './IAssetAnimationFramePartItem'; + +export interface IAssetAnimationFramePart +{ + id?: string; + frame?: number; + base?: string; + action?: string; + dx?: number; + dy?: number; + dz?: number; + dd?: number; + items?: IAssetAnimationFramePartItem[]; +} diff --git a/src/core/asset/interfaces/animation/IAssetAnimationFramePartItem.ts b/src/core/asset/interfaces/animation/IAssetAnimationFramePartItem.ts new file mode 100644 index 00000000..45a76423 --- /dev/null +++ b/src/core/asset/interfaces/animation/IAssetAnimationFramePartItem.ts @@ -0,0 +1,5 @@ +export interface IAssetAnimationFramePartItem +{ + id?: string; + base?: string; +} diff --git a/src/core/asset/interfaces/animation/IAssetAnimationOverride.ts b/src/core/asset/interfaces/animation/IAssetAnimationOverride.ts new file mode 100644 index 00000000..3d568330 --- /dev/null +++ b/src/core/asset/interfaces/animation/IAssetAnimationOverride.ts @@ -0,0 +1,8 @@ +import { IAssetAnimationFrame } from './IAssetAnimationFrame'; + +export interface IAssetAnimationOverride +{ + name?: string; + override?: string; + frames?: IAssetAnimationFrame[]; +} diff --git a/src/core/asset/interfaces/animation/IAssetAnimationRemove.ts b/src/core/asset/interfaces/animation/IAssetAnimationRemove.ts new file mode 100644 index 00000000..ac65fb59 --- /dev/null +++ b/src/core/asset/interfaces/animation/IAssetAnimationRemove.ts @@ -0,0 +1,4 @@ +export interface IAssetAnimationRemove +{ + id?: string; +} diff --git a/src/core/asset/interfaces/animation/IAssetAnimationShadow.ts b/src/core/asset/interfaces/animation/IAssetAnimationShadow.ts new file mode 100644 index 00000000..dfe22a88 --- /dev/null +++ b/src/core/asset/interfaces/animation/IAssetAnimationShadow.ts @@ -0,0 +1,4 @@ +export interface IAssetAnimationShadow +{ + id?: string; +} diff --git a/src/core/asset/interfaces/animation/IAssetAnimationSprite.ts b/src/core/asset/interfaces/animation/IAssetAnimationSprite.ts new file mode 100644 index 00000000..afc7b055 --- /dev/null +++ b/src/core/asset/interfaces/animation/IAssetAnimationSprite.ts @@ -0,0 +1,11 @@ +import { IAssetAnimationSpriteDirection } from './IAssetAnimationSpriteDirection'; + +export interface IAssetAnimationSprite +{ + id?: string; + member?: string; + directions?: number; + staticY?: number; + ink?: number; + directionList?: IAssetAnimationSpriteDirection[]; +} diff --git a/src/core/asset/interfaces/animation/IAssetAnimationSpriteDirection.ts b/src/core/asset/interfaces/animation/IAssetAnimationSpriteDirection.ts new file mode 100644 index 00000000..746719d6 --- /dev/null +++ b/src/core/asset/interfaces/animation/IAssetAnimationSpriteDirection.ts @@ -0,0 +1,7 @@ +export interface IAssetAnimationSpriteDirection +{ + id?: number; + dx?: number; + dy?: number; + dz?: number; +} diff --git a/src/core/asset/interfaces/animation/index.ts b/src/core/asset/interfaces/animation/index.ts new file mode 100644 index 00000000..56543d0b --- /dev/null +++ b/src/core/asset/interfaces/animation/index.ts @@ -0,0 +1,12 @@ +export * from './IAssetAnimation'; +export * from './IAssetAnimationAdd'; +export * from './IAssetAnimationAvatar'; +export * from './IAssetAnimationDirection'; +export * from './IAssetAnimationFrame'; +export * from './IAssetAnimationFramePart'; +export * from './IAssetAnimationFramePartItem'; +export * from './IAssetAnimationOverride'; +export * from './IAssetAnimationRemove'; +export * from './IAssetAnimationShadow'; +export * from './IAssetAnimationSprite'; +export * from './IAssetAnimationSpriteDirection'; diff --git a/src/core/asset/interfaces/index.ts b/src/core/asset/interfaces/index.ts new file mode 100644 index 00000000..eb113bd8 --- /dev/null +++ b/src/core/asset/interfaces/index.ts @@ -0,0 +1,8 @@ +export * from './animation'; +export * from './IAsset'; +export * from './IAssetAlias'; +export * from './IAssetData'; +export * from './IAssetDimension'; +export * from './IAssetPalette'; +export * from './spritesheet'; +export * from './visualization'; diff --git a/src/core/asset/interfaces/spritesheet/ISpritesheetData.ts b/src/core/asset/interfaces/spritesheet/ISpritesheetData.ts new file mode 100644 index 00000000..24389cc7 --- /dev/null +++ b/src/core/asset/interfaces/spritesheet/ISpritesheetData.ts @@ -0,0 +1,8 @@ +import { ISpritesheetFrame } from './ISpritesheetFrame'; +import { ISpritesheetMeta } from './ISpritesheetMeta'; + +export interface ISpritesheetData +{ + meta?: ISpritesheetMeta; + frames?: { [index: string]: ISpritesheetFrame }; +} diff --git a/src/core/asset/interfaces/spritesheet/ISpritesheetFrame.ts b/src/core/asset/interfaces/spritesheet/ISpritesheetFrame.ts new file mode 100644 index 00000000..0833b502 --- /dev/null +++ b/src/core/asset/interfaces/spritesheet/ISpritesheetFrame.ts @@ -0,0 +1,25 @@ +export interface ISpritesheetFrame +{ + frame: { + x: number; + y: number; + w: number; + h: number; + }; + rotated: boolean; + trimmed: boolean; + spriteSourceSize: { + x: number; + y: number; + w: number; + h: number; + }; + sourceSize: { + w: number; + h: number; + }; + pivot: { + x: number; + y: number; + }; +} diff --git a/src/core/asset/interfaces/spritesheet/ISpritesheetMeta.ts b/src/core/asset/interfaces/spritesheet/ISpritesheetMeta.ts new file mode 100644 index 00000000..3a74f7bc --- /dev/null +++ b/src/core/asset/interfaces/spritesheet/ISpritesheetMeta.ts @@ -0,0 +1,12 @@ +export interface ISpritesheetMeta +{ + app: string; + version: string; + image: string; + format: string; + size: { + w: number; + h: number; + }; + scale: string; +} diff --git a/src/core/asset/interfaces/spritesheet/index.ts b/src/core/asset/interfaces/spritesheet/index.ts new file mode 100644 index 00000000..9c94e8ba --- /dev/null +++ b/src/core/asset/interfaces/spritesheet/index.ts @@ -0,0 +1,3 @@ +export * from './ISpritesheetData'; +export * from './ISpritesheetFrame'; +export * from './ISpritesheetMeta'; diff --git a/src/core/asset/interfaces/visualization/IAssetVisualizationData.ts b/src/core/asset/interfaces/visualization/IAssetVisualizationData.ts new file mode 100644 index 00000000..e0a2d1de --- /dev/null +++ b/src/core/asset/interfaces/visualization/IAssetVisualizationData.ts @@ -0,0 +1,19 @@ +import { IAssetVisualAnimation } from './animation/IAssetVisualAnimation'; +import { IAssetColor } from './color/IAssetColor'; +import { IAssetGesture } from './gestures/IAssetGesture'; +import { IAssetVisualizationDirection } from './IAssetVisualizationDirection'; +import { IAssetVisualizationLayer } from './IAssetVisualizationLayer'; +import { IAssetPosture } from './postures/IAssetPosture'; + +export interface IAssetVisualizationData +{ + size?: number; + layerCount?: number; + angle?: number; + layers?: { [index: string]: IAssetVisualizationLayer }; + colors?: { [index: string]: IAssetColor }; + directions?: { [index: string]: IAssetVisualizationDirection }; + animations?: { [index: string]: IAssetVisualAnimation }; + postures?: { [index: string]: IAssetPosture }; + gestures?: { [index: string]: IAssetGesture }; +} diff --git a/src/core/asset/interfaces/visualization/IAssetVisualizationDirection.ts b/src/core/asset/interfaces/visualization/IAssetVisualizationDirection.ts new file mode 100644 index 00000000..cc628f10 --- /dev/null +++ b/src/core/asset/interfaces/visualization/IAssetVisualizationDirection.ts @@ -0,0 +1,6 @@ +import { IAssetVisualizationLayer } from './IAssetVisualizationLayer'; + +export interface IAssetVisualizationDirection +{ + layers?: { [index: string]: IAssetVisualizationLayer }; +} diff --git a/src/core/asset/interfaces/visualization/IAssetVisualizationLayer.ts b/src/core/asset/interfaces/visualization/IAssetVisualizationLayer.ts new file mode 100644 index 00000000..61fcf56e --- /dev/null +++ b/src/core/asset/interfaces/visualization/IAssetVisualizationLayer.ts @@ -0,0 +1,10 @@ +export interface IAssetVisualizationLayer +{ + x?: number; + y?: number; + z?: number; + alpha?: number; + ink?: string; + tag?: string; + ignoreMouse?: boolean; +} \ No newline at end of file diff --git a/src/core/asset/interfaces/visualization/animation/IAssetVisualAnimation.ts b/src/core/asset/interfaces/visualization/animation/IAssetVisualAnimation.ts new file mode 100644 index 00000000..4e714389 --- /dev/null +++ b/src/core/asset/interfaces/visualization/animation/IAssetVisualAnimation.ts @@ -0,0 +1,10 @@ +import { IAssetVisualAnimationLayer } from './IAssetVisualAnimationLayer'; + +export interface IAssetVisualAnimation +{ + transitionTo?: number; + transitionFrom?: number; + immediateChangeFrom?: string; + randomStart?: boolean; + layers?: { [index: string]: IAssetVisualAnimationLayer }; +} diff --git a/src/core/asset/interfaces/visualization/animation/IAssetVisualAnimationLayer.ts b/src/core/asset/interfaces/visualization/animation/IAssetVisualAnimationLayer.ts new file mode 100644 index 00000000..2a274ea6 --- /dev/null +++ b/src/core/asset/interfaces/visualization/animation/IAssetVisualAnimationLayer.ts @@ -0,0 +1,9 @@ +import { IAssetVisualAnimationSequence } from './IAssetVisualAnimationSequence'; + +export interface IAssetVisualAnimationLayer +{ + loopCount?: number; + frameRepeat?: number; + random?: number; + frameSequences?: { [index: string]: IAssetVisualAnimationSequence }; +} diff --git a/src/core/asset/interfaces/visualization/animation/IAssetVisualAnimationSequence.ts b/src/core/asset/interfaces/visualization/animation/IAssetVisualAnimationSequence.ts new file mode 100644 index 00000000..bb25104c --- /dev/null +++ b/src/core/asset/interfaces/visualization/animation/IAssetVisualAnimationSequence.ts @@ -0,0 +1,8 @@ +import { IAssetVisualAnimationSequenceFrame } from './IAssetVisualAnimationSequenceFrame'; + +export interface IAssetVisualAnimationSequence +{ + loopCount?: number; + random?: number; + frames?: { [index: string]: IAssetVisualAnimationSequenceFrame }; +} diff --git a/src/core/asset/interfaces/visualization/animation/IAssetVisualAnimationSequenceFrame.ts b/src/core/asset/interfaces/visualization/animation/IAssetVisualAnimationSequenceFrame.ts new file mode 100644 index 00000000..196631e5 --- /dev/null +++ b/src/core/asset/interfaces/visualization/animation/IAssetVisualAnimationSequenceFrame.ts @@ -0,0 +1,11 @@ +import { IAssetVisualAnimationSequenceFrameOffset } from './IAssetVisualAnimationSequenceFrameOffset'; + +export interface IAssetVisualAnimationSequenceFrame +{ + id?: number; + x?: number; + y?: number; + randomX?: number; + randomY?: number; + offsets?: { [index: string]: IAssetVisualAnimationSequenceFrameOffset }; +} diff --git a/src/core/asset/interfaces/visualization/animation/IAssetVisualAnimationSequenceFrameOffset.ts b/src/core/asset/interfaces/visualization/animation/IAssetVisualAnimationSequenceFrameOffset.ts new file mode 100644 index 00000000..bc85461b --- /dev/null +++ b/src/core/asset/interfaces/visualization/animation/IAssetVisualAnimationSequenceFrameOffset.ts @@ -0,0 +1,6 @@ +export interface IAssetVisualAnimationSequenceFrameOffset +{ + direction?: number; + x?: number; + y?: number; +} diff --git a/src/core/asset/interfaces/visualization/animation/index.ts b/src/core/asset/interfaces/visualization/animation/index.ts new file mode 100644 index 00000000..19b332cc --- /dev/null +++ b/src/core/asset/interfaces/visualization/animation/index.ts @@ -0,0 +1,5 @@ +export * from './IAssetVisualAnimation'; +export * from './IAssetVisualAnimationLayer'; +export * from './IAssetVisualAnimationSequence'; +export * from './IAssetVisualAnimationSequenceFrame'; +export * from './IAssetVisualAnimationSequenceFrameOffset'; diff --git a/src/core/asset/interfaces/visualization/color/IAssetColor.ts b/src/core/asset/interfaces/visualization/color/IAssetColor.ts new file mode 100644 index 00000000..29ebc750 --- /dev/null +++ b/src/core/asset/interfaces/visualization/color/IAssetColor.ts @@ -0,0 +1,6 @@ +import { IAssetColorLayer } from './IAssetColorLayer'; + +export interface IAssetColor +{ + layers?: { [index: string]: IAssetColorLayer }; +} diff --git a/src/core/asset/interfaces/visualization/color/IAssetColorLayer.ts b/src/core/asset/interfaces/visualization/color/IAssetColorLayer.ts new file mode 100644 index 00000000..7a1372e2 --- /dev/null +++ b/src/core/asset/interfaces/visualization/color/IAssetColorLayer.ts @@ -0,0 +1,4 @@ +export interface IAssetColorLayer +{ + color?: number; +} diff --git a/src/core/asset/interfaces/visualization/color/index.ts b/src/core/asset/interfaces/visualization/color/index.ts new file mode 100644 index 00000000..00aff50c --- /dev/null +++ b/src/core/asset/interfaces/visualization/color/index.ts @@ -0,0 +1,2 @@ +export * from './IAssetColor'; +export * from './IAssetColorLayer'; diff --git a/src/core/asset/interfaces/visualization/gestures/IAssetGesture.ts b/src/core/asset/interfaces/visualization/gestures/IAssetGesture.ts new file mode 100644 index 00000000..ddf3752f --- /dev/null +++ b/src/core/asset/interfaces/visualization/gestures/IAssetGesture.ts @@ -0,0 +1,5 @@ +export interface IAssetGesture +{ + id?: string; + animationId?: number; +} diff --git a/src/core/asset/interfaces/visualization/gestures/index.ts b/src/core/asset/interfaces/visualization/gestures/index.ts new file mode 100644 index 00000000..2c6e978a --- /dev/null +++ b/src/core/asset/interfaces/visualization/gestures/index.ts @@ -0,0 +1 @@ +export * from './IAssetGesture'; diff --git a/src/core/asset/interfaces/visualization/index.ts b/src/core/asset/interfaces/visualization/index.ts new file mode 100644 index 00000000..334bddcc --- /dev/null +++ b/src/core/asset/interfaces/visualization/index.ts @@ -0,0 +1,7 @@ +export * from './animation'; +export * from './color'; +export * from './gestures'; +export * from './IAssetVisualizationData'; +export * from './IAssetVisualizationDirection'; +export * from './IAssetVisualizationLayer'; +export * from './postures'; diff --git a/src/core/asset/interfaces/visualization/postures/IAssetPosture.ts b/src/core/asset/interfaces/visualization/postures/IAssetPosture.ts new file mode 100644 index 00000000..33138514 --- /dev/null +++ b/src/core/asset/interfaces/visualization/postures/IAssetPosture.ts @@ -0,0 +1,5 @@ +export interface IAssetPosture +{ + id?: string; + animationId?: number; +} diff --git a/src/core/asset/interfaces/visualization/postures/index.ts b/src/core/asset/interfaces/visualization/postures/index.ts new file mode 100644 index 00000000..c24c1b93 --- /dev/null +++ b/src/core/asset/interfaces/visualization/postures/index.ts @@ -0,0 +1 @@ +export * from './IAssetPosture'; diff --git a/src/core/common/INitroManager.ts b/src/core/common/INitroManager.ts new file mode 100644 index 00000000..d502b2b3 --- /dev/null +++ b/src/core/common/INitroManager.ts @@ -0,0 +1,12 @@ +import { IEventDispatcher } from '../events/IEventDispatcher'; +import { IDisposable } from './disposable/IDisposable'; +import { INitroLogger } from './logger/INitroLogger'; + +export interface INitroManager extends IDisposable +{ + init(): void; + logger: INitroLogger; + events: IEventDispatcher; + isLoaded: boolean; + isLoading: boolean; +} \ No newline at end of file diff --git a/src/core/common/IUpdateReceiver.ts b/src/core/common/IUpdateReceiver.ts new file mode 100644 index 00000000..51608b4c --- /dev/null +++ b/src/core/common/IUpdateReceiver.ts @@ -0,0 +1,6 @@ +import { IDisposable } from './disposable/IDisposable'; + +export interface IUpdateReceiver extends IDisposable +{ + update(time: number): void; +} \ No newline at end of file diff --git a/src/core/common/NitroManager.ts b/src/core/common/NitroManager.ts new file mode 100644 index 00000000..091e175c --- /dev/null +++ b/src/core/common/NitroManager.ts @@ -0,0 +1,78 @@ +import { EventDispatcher } from '../events/EventDispatcher'; +import { IEventDispatcher } from '../events/IEventDispatcher'; +import { Disposable } from './disposable/Disposable'; +import { INitroManager } from './INitroManager'; +import { INitroLogger } from './logger/INitroLogger'; +import { NitroLogger } from './logger/NitroLogger'; + +export class NitroManager extends Disposable implements INitroManager +{ + private _logger: INitroLogger; + + private _events: IEventDispatcher; + + private _isLoaded: boolean; + private _isLoading: boolean; + + constructor(logger: INitroLogger = null) + { + super(); + + this._logger = logger instanceof NitroLogger ? logger : new NitroLogger(this.constructor.name); + + this._events = new EventDispatcher(); + + this._isLoaded = false; + this._isLoading = false; + } + + public init(): void + { + if(this._isLoaded || this._isLoading || this.isDisposing) return; + + this._isLoading = true; + + this.onInit(); + + this._isLoaded = true; + this._isLoading = false; + } + + protected onInit(): void + { + return; + } + + protected onDispose(): void + { + if(this._events) this._events.dispose(); + + super.onDispose(); + } + + public reload(): void + { + this.dispose(); + this.init(); + } + + public get logger(): INitroLogger + { + return this._logger; + } + + public get events(): IEventDispatcher + { + return this._events; + } + + public get isLoaded(): boolean + { + return this._isLoaded; + } + + public get isLoading(): boolean + { + return this._isLoading; + } +} \ No newline at end of file diff --git a/src/core/common/disposable/Disposable.ts b/src/core/common/disposable/Disposable.ts new file mode 100644 index 00000000..0b77bcf7 --- /dev/null +++ b/src/core/common/disposable/Disposable.ts @@ -0,0 +1,40 @@ +import { IDisposable } from './IDisposable'; + +export class Disposable implements IDisposable +{ + protected _isDisposed: boolean; + protected _isDisposing: boolean; + + constructor() + { + this._isDisposed = false; + this._isDisposing = false; + } + + public dispose(): void + { + if(this._isDisposed || this._isDisposing) return; + + this._isDisposing = true; + + this.onDispose(); + + this._isDisposed = true; + this._isDisposing = false; + } + + protected onDispose(): void + { + return; + } + + public get disposed(): boolean + { + return this._isDisposed; + } + + public get isDisposing(): boolean + { + return this._isDisposing; + } +} \ No newline at end of file diff --git a/src/core/common/disposable/IDisposable.ts b/src/core/common/disposable/IDisposable.ts new file mode 100644 index 00000000..b9f60402 --- /dev/null +++ b/src/core/common/disposable/IDisposable.ts @@ -0,0 +1,5 @@ +export interface IDisposable +{ + dispose(): void; + disposed: boolean; +} \ No newline at end of file diff --git a/src/core/common/disposable/index.ts b/src/core/common/disposable/index.ts new file mode 100644 index 00000000..2edb6e9f --- /dev/null +++ b/src/core/common/disposable/index.ts @@ -0,0 +1,2 @@ +export * from './Disposable'; +export * from './IDisposable'; diff --git a/src/core/common/index.ts b/src/core/common/index.ts new file mode 100644 index 00000000..50a8f018 --- /dev/null +++ b/src/core/common/index.ts @@ -0,0 +1,5 @@ +export * from './disposable'; +export * from './INitroManager'; +export * from './IUpdateReceiver'; +export * from './logger'; +export * from './NitroManager'; diff --git a/src/core/common/logger/INitroLogger.ts b/src/core/common/logger/INitroLogger.ts new file mode 100644 index 00000000..cbfd1979 --- /dev/null +++ b/src/core/common/logger/INitroLogger.ts @@ -0,0 +1,8 @@ +export interface INitroLogger +{ + log(message: string): void; + error(message: string, trace?: string): void; + warn(message: string): void; + description: string | number; + print: boolean; +} \ No newline at end of file diff --git a/src/core/common/logger/NitroLogger.ts b/src/core/common/logger/NitroLogger.ts new file mode 100644 index 00000000..d2074498 --- /dev/null +++ b/src/core/common/logger/NitroLogger.ts @@ -0,0 +1,89 @@ +import { INitroLogger } from './INitroLogger'; + +export class NitroLogger implements INitroLogger +{ + private static LAST_TIMESTAMP: number = Date.now(); + + private _name: string; + private _description: string | number; + private _print: boolean; + + constructor(name: string, description: string | number = null) + { + this._name = name; + this._description = description; + this._print = true; + } + + public log(message: string): void + { + this.printMessage(message, 'log'); + } + + public error(message: string, trace?: string): void + { + this.printMessage(trace || message, 'error'); + } + + public warn(message: string): void + { + this.printMessage(message, 'warn'); + } + + public printMessage(message: string, modus: string): void + { + if(!this._print) return; + + NitroLogger.log(message, this._name, modus); + } + + public static log(message: string, name: string = 'Nitro', modus: string = null): void + { + const logString = `[Nitro] ${ new Date().toDateString() } [${ name }] ${ message } ${ this.getTimestamp() }`; + + switch(modus) + { + case 'error': + console.error(logString); + break; + case 'warn': + console.warn(logString); + break; + case 'log': + default: + console.log(logString); + break; + } + } + + public static getTimestamp(): string + { + const now = Date.now(); + + const result = ` +${ now - NitroLogger.LAST_TIMESTAMP || 0 }ms`; + + this.LAST_TIMESTAMP = now; + + return result; + } + + public get description(): string | number + { + return this._description; + } + + public set description(description: string | number) + { + this._description = description; + } + + public get print(): boolean + { + return this._print; + } + + public set print(flag: boolean) + { + this._print = flag; + } +} diff --git a/src/core/common/logger/index.ts b/src/core/common/logger/index.ts new file mode 100644 index 00000000..147aa164 --- /dev/null +++ b/src/core/common/logger/index.ts @@ -0,0 +1,2 @@ +export * from './INitroLogger'; +export * from './NitroLogger'; diff --git a/src/core/communication/CommunicationManager.ts b/src/core/communication/CommunicationManager.ts new file mode 100644 index 00000000..1ecb4b59 --- /dev/null +++ b/src/core/communication/CommunicationManager.ts @@ -0,0 +1,53 @@ +import { Disposable } from '../common/disposable/Disposable'; +import { IUpdateReceiver } from '../common/IUpdateReceiver'; +import { IConnection } from './connections/IConnection'; +import { IConnectionStateListener } from './connections/IConnectionStateListener'; +import { SocketConnection } from './connections/SocketConnection'; +import { ICommunicationManager } from './ICommunicationManager'; + +export class CommunicationManager extends Disposable implements ICommunicationManager, IUpdateReceiver +{ + private _connections: IConnection[] + + constructor() + { + super(); + + this._connections = []; + } + + protected onDispose(): void + { + if(!this._connections || !this._connections.length) return; + + for(const connection of this._connections.values()) connection && connection.dispose(); + } + + public createConnection(stateListener: IConnectionStateListener = null): IConnection + { + const connection = new SocketConnection(this, stateListener); + + if(!connection) return; + + this._connections.push(connection); + + return connection; + } + + public update(time: number): void + { + let index = 0; + + while(index < this._connections.length) + { + const connection = this._connections[index]; + + connection.processReceivedData(); + + if(this.disposed) return; + + if(connection.disposed) this._connections.splice(index, 1); + else index++; + } + } +} \ No newline at end of file diff --git a/src/core/communication/ICommunicationManager.ts b/src/core/communication/ICommunicationManager.ts new file mode 100644 index 00000000..532e0be4 --- /dev/null +++ b/src/core/communication/ICommunicationManager.ts @@ -0,0 +1,8 @@ +import { IDisposable } from '../common/disposable/IDisposable'; +import { IConnection } from './connections/IConnection'; +import { IConnectionStateListener } from './connections/IConnectionStateListener'; + +export interface ICommunicationManager extends IDisposable +{ + createConnection(stateListener?: IConnectionStateListener): IConnection; +} \ No newline at end of file diff --git a/src/core/communication/codec/BinaryReader.ts b/src/core/communication/codec/BinaryReader.ts new file mode 100644 index 00000000..6409eb82 --- /dev/null +++ b/src/core/communication/codec/BinaryReader.ts @@ -0,0 +1,62 @@ +export class BinaryReader +{ + private _position: number; + private _dataView: DataView; + + constructor(buffer: ArrayBuffer) + { + this._position = 0; + this._dataView = new DataView(buffer); + } + + public readByte(): number + { + const byte = this._dataView.getInt8(this._position); + + this._position++; + + return byte; + } + + public readBytes(length: number): BinaryReader + { + const buffer = new BinaryReader(this._dataView.buffer.slice(this._position, this._position + length)); + + this._position += length; + + return buffer; + } + + public readShort(): number + { + const short = this._dataView.getInt16(this._position); + + this._position += 2; + + return short; + } + + public readInt(): number + { + const int = this._dataView.getInt32(this._position); + + this._position += 4; + + return int; + } + + public remaining(): number + { + return this._dataView.byteLength - this._position; + } + + public toString(encoding?: string): string + { + return new TextDecoder().decode(this._dataView.buffer); + } + + public toArrayBuffer(): ArrayBuffer + { + return this._dataView.buffer; + } +} \ No newline at end of file diff --git a/src/core/communication/codec/BinaryWriter.ts b/src/core/communication/codec/BinaryWriter.ts new file mode 100644 index 00000000..8eae1ef7 --- /dev/null +++ b/src/core/communication/codec/BinaryWriter.ts @@ -0,0 +1,94 @@ +export class BinaryWriter +{ + private _buffer: Uint8Array; + + constructor() + { + this._buffer = new Uint8Array(); + } + + public writeByte(byte: number): BinaryWriter + { + const array = new Uint8Array(1); + + array[0] = byte; + + this.appendArray(array); + + return this; + } + + public writeBytes(bytes: ArrayBuffer): BinaryWriter + { + const array = new Uint8Array(bytes); + + this.appendArray(array); + + return this; + } + + public writeShort(short: number): BinaryWriter + { + const array = new Uint8Array(2); + + array[0] = short >> 8; + array[1] = short & 0xFF; + + this.appendArray(array); + + return this; + } + + public writeInt(integer: number): BinaryWriter + { + const array = new Uint8Array(4); + + array[0] = integer >> 24; + array[1] = integer >> 16; + array[2] = integer >> 8; + array[3] = integer & 0xFF; + + this.appendArray(array); + + return this; + } + + public writeString(string: string, includeLength: boolean = true): BinaryWriter + { + const array = new TextEncoder().encode(string); + + if(includeLength) + { + this.writeShort(array.length); + this.appendArray(array); + } + else + { + this.appendArray(array); + } + + return this; + } + + private appendArray(array: Uint8Array): void + { + if(!array) return; + + const mergedArray = new Uint8Array(this._buffer.length + array.length); + + mergedArray.set(this._buffer); + mergedArray.set(array, this._buffer.length); + + this._buffer = mergedArray; + } + + public getBuffer(): ArrayBuffer + { + return this._buffer.buffer; + } + + public toString(encoding?: string): string + { + return new TextDecoder(encoding).decode(this._buffer); + } +} \ No newline at end of file diff --git a/src/core/communication/codec/Byte.ts b/src/core/communication/codec/Byte.ts new file mode 100644 index 00000000..dbcb29cd --- /dev/null +++ b/src/core/communication/codec/Byte.ts @@ -0,0 +1,14 @@ +export class Byte +{ + private _value: number; + + constructor(value: number) + { + this._value = value; + } + + public get value(): number + { + return this._value; + } +} \ No newline at end of file diff --git a/src/core/communication/codec/ICodec.ts b/src/core/communication/codec/ICodec.ts new file mode 100644 index 00000000..824d7f80 --- /dev/null +++ b/src/core/communication/codec/ICodec.ts @@ -0,0 +1,9 @@ +import { BinaryWriter } from './BinaryWriter'; +import { IConnection } from '../connections/IConnection'; +import { IMessageDataWrapper } from '../messages/IMessageDataWrapper'; + +export interface ICodec +{ + encode(header: number, messages: any[]): BinaryWriter; + decode(connection: IConnection): IMessageDataWrapper[]; +} \ No newline at end of file diff --git a/src/core/communication/codec/Short.ts b/src/core/communication/codec/Short.ts new file mode 100644 index 00000000..f23125e4 --- /dev/null +++ b/src/core/communication/codec/Short.ts @@ -0,0 +1,14 @@ +export class Short +{ + private _value: number; + + constructor(value: number) + { + this._value = value; + } + + public get value(): number + { + return this._value; + } +} \ No newline at end of file diff --git a/src/core/communication/codec/evawire/EvaWireDataWrapper.ts b/src/core/communication/codec/evawire/EvaWireDataWrapper.ts new file mode 100644 index 00000000..c03c45e1 --- /dev/null +++ b/src/core/communication/codec/evawire/EvaWireDataWrapper.ts @@ -0,0 +1,65 @@ +import { IMessageDataWrapper } from '../../messages/IMessageDataWrapper'; +import { BinaryReader } from '../BinaryReader'; + +export class EvaWireDataWrapper implements IMessageDataWrapper +{ + private _header: number; + private _buffer: BinaryReader; + + constructor(header: number, buffer: BinaryReader) + { + this._header = header; + this._buffer = buffer; + } + + public readByte(): number + { + if(!this._buffer) return -1; + + return this._buffer.readByte(); + } + + public readBytes(length: number): BinaryReader + { + if(!this._buffer) return null; + + return this._buffer.readBytes(length); + } + + public readBoolean(): boolean + { + return (this.readByte() === 1); + } + + public readShort(): number + { + if(!this._buffer) return -1; + + return this._buffer.readShort(); + } + + public readInt(): number + { + if(!this._buffer) return -1; + + return this._buffer.readInt(); + } + + public readString(): string + { + const length = this.readShort(); + const buffer = this._buffer.readBytes(length); + + return buffer.toString('utf8'); + } + + public get header(): number + { + return this._header; + } + + public get bytesAvailable(): boolean + { + return (this._buffer && (this._buffer.remaining() > 0)); + } +} \ No newline at end of file diff --git a/src/core/communication/codec/evawire/EvaWireFormat.ts b/src/core/communication/codec/evawire/EvaWireFormat.ts new file mode 100644 index 00000000..d591e09c --- /dev/null +++ b/src/core/communication/codec/evawire/EvaWireFormat.ts @@ -0,0 +1,87 @@ +import { IConnection } from '../../connections/IConnection'; +import { IMessageDataWrapper } from '../../messages/IMessageDataWrapper'; +import { BinaryReader } from '../BinaryReader'; +import { BinaryWriter } from '../BinaryWriter'; +import { Byte } from '../Byte'; +import { ICodec } from '../ICodec'; +import { Short } from '../Short'; +import { EvaWireDataWrapper } from './EvaWireDataWrapper'; + +export class EvaWireFormat implements ICodec +{ + public encode(header: number, messages: any[]): BinaryWriter + { + const writer = new BinaryWriter(); + + writer.writeShort(header); + + for(const value of messages) + { + let type: string = typeof value; + + if(type === 'object') + { + if(value === null) type = 'null'; + else if(value instanceof Byte) type = 'byte'; + else if(value instanceof Short) type = 'short'; + } + + switch(type) + { + case 'null': + writer.writeShort(0); + break; + case 'byte': + writer.writeByte(value.value); + break; + case 'short': + writer.writeShort(value.value); + break; + case 'number': + writer.writeInt(value); + break; + case 'boolean': + writer.writeByte(value ? 1 : 0); + break; + case 'string': + if(!value) writer.writeShort(0); + else + { + writer.writeString(value, true); + } + break; + } + } + + const buffer = writer.getBuffer(); + + if(!buffer) return null; + + return new BinaryWriter().writeInt(buffer.byteLength).writeBytes(buffer); + } + + public decode(connection: IConnection): IMessageDataWrapper[] + { + if(!connection || !connection.dataBuffer || !connection.dataBuffer.byteLength) return null; + + const wrappers: IMessageDataWrapper[] = []; + + while(connection.dataBuffer.byteLength) + { + if(connection.dataBuffer.byteLength < 4) break; + + const container = new BinaryReader(connection.dataBuffer); + const length = container.readInt(); + + if(length > (connection.dataBuffer.byteLength - 4)) break; + + const extracted = container.readBytes(length); + + wrappers.push(new EvaWireDataWrapper(extracted.readShort(), extracted)); + + connection.dataBuffer = connection.dataBuffer.slice(length + 4); + } + + return wrappers; + } +} \ No newline at end of file diff --git a/src/core/communication/codec/evawire/index.ts b/src/core/communication/codec/evawire/index.ts new file mode 100644 index 00000000..6b63cda9 --- /dev/null +++ b/src/core/communication/codec/evawire/index.ts @@ -0,0 +1,2 @@ +export * from './EvaWireDataWrapper'; +export * from './EvaWireFormat'; diff --git a/src/core/communication/codec/index.ts b/src/core/communication/codec/index.ts new file mode 100644 index 00000000..ae6e3432 --- /dev/null +++ b/src/core/communication/codec/index.ts @@ -0,0 +1,6 @@ +export * from './BinaryReader'; +export * from './BinaryWriter'; +export * from './Byte'; +export * from './evawire'; +export * from './ICodec'; +export * from './Short'; diff --git a/src/core/communication/connections/IConnection.ts b/src/core/communication/connections/IConnection.ts new file mode 100644 index 00000000..a00a07db --- /dev/null +++ b/src/core/communication/connections/IConnection.ts @@ -0,0 +1,19 @@ +import { IEventDispatcher } from '../../events/IEventDispatcher'; +import { IMessageComposer } from '../messages/IMessageComposer'; +import { IMessageConfiguration } from '../messages/IMessageConfiguration'; +import { IMessageEvent } from '../messages/IMessageEvent'; + +export interface IConnection extends IEventDispatcher +{ + init(socketUrl: string): void; + dispose(): void; + onReady(): void; + authenticated(): void; + send(...composers: IMessageComposer[]): void; + processReceivedData(): void; + registerMessages(configuration: IMessageConfiguration): void; + addMessageEvent(event: IMessageEvent): void; + removeMessageEvent(event: IMessageEvent): void; + isAuthenticated: boolean; + dataBuffer: ArrayBuffer; +} \ No newline at end of file diff --git a/src/core/communication/connections/IConnectionStateListener.ts b/src/core/communication/connections/IConnectionStateListener.ts new file mode 100644 index 00000000..d140fd03 --- /dev/null +++ b/src/core/communication/connections/IConnectionStateListener.ts @@ -0,0 +1,4 @@ +export interface IConnectionStateListener +{ + connectionInit(socketUrl: string): void; +} \ No newline at end of file diff --git a/src/core/communication/connections/SocketConnection.ts b/src/core/communication/connections/SocketConnection.ts new file mode 100644 index 00000000..3114ef41 --- /dev/null +++ b/src/core/communication/connections/SocketConnection.ts @@ -0,0 +1,368 @@ +import { Nitro } from '../../../nitro/Nitro'; +import { NitroLogger } from '../../common/logger/NitroLogger'; +import { EventDispatcher } from '../../events/EventDispatcher'; +import { EvaWireFormat } from '../codec/evawire/EvaWireFormat'; +import { ICodec } from '../codec/ICodec'; +import { SocketConnectionEvent } from '../events/SocketConnectionEvent'; +import { ICommunicationManager } from '../ICommunicationManager'; +import { IMessageComposer } from '../messages/IMessageComposer'; +import { IMessageConfiguration } from '../messages/IMessageConfiguration'; +import { IMessageDataWrapper } from '../messages/IMessageDataWrapper'; +import { IMessageEvent } from '../messages/IMessageEvent'; +import { MessageClassManager } from '../messages/MessageClassManager'; +import { WebSocketEventEnum } from './enums/WebSocketEventEnum'; +import { IConnection } from './IConnection'; +import { IConnectionStateListener } from './IConnectionStateListener'; + +export class SocketConnection extends EventDispatcher implements IConnection +{ + private _communicationManager: ICommunicationManager; + private _stateListener: IConnectionStateListener; + private _socket: WebSocket; + private _messages: MessageClassManager; + private _codec: ICodec; + private _dataBuffer: ArrayBuffer; + private _isReady: boolean; + + private _pendingClientMessages: IMessageComposer[]; + private _pendingServerMessages: IMessageDataWrapper[]; + + private _isAuthenticated: boolean; + + constructor(communicationManager: ICommunicationManager, stateListener: IConnectionStateListener) + { + super(); + + this._communicationManager = communicationManager; + this._stateListener = stateListener; + this._socket = null; + this._messages = new MessageClassManager(); + this._codec = new EvaWireFormat(); + this._dataBuffer = null; + this._isReady = false; + + this._pendingClientMessages = []; + this._pendingServerMessages = []; + + this._isAuthenticated = false; + + this.onOpen = this.onOpen.bind(this); + this.onClose = this.onClose.bind(this); + this.onError = this.onError.bind(this); + this.onMessage = this.onMessage.bind(this); + } + + public init(socketUrl: string): void + { + if(this._stateListener) + { + this._stateListener.connectionInit(socketUrl); + } + + this.createSocket(socketUrl); + } + + protected onDispose(): void + { + super.onDispose(); + + this.destroySocket(); + + this._communicationManager = null; + this._stateListener = null; + this._messages = null; + this._codec = null; + this._dataBuffer = null; + } + + public onReady(): void + { + if(this._isReady) return; + + this._isReady = true; + + if(this._pendingServerMessages && this._pendingServerMessages.length) this.processWrappers(...this._pendingServerMessages); + + if(this._pendingClientMessages && this._pendingClientMessages.length) this.send(...this._pendingClientMessages); + + this._pendingServerMessages = []; + this._pendingClientMessages = []; + } + + private createSocket(socketUrl: string): void + { + if(!socketUrl) return; + + this.destroySocket(); + + this._dataBuffer = new ArrayBuffer(0); + this._socket = new WebSocket(socketUrl); + + this._socket.addEventListener(WebSocketEventEnum.CONNECTION_OPENED, this.onOpen); + this._socket.addEventListener(WebSocketEventEnum.CONNECTION_CLOSED, this.onClose); + this._socket.addEventListener(WebSocketEventEnum.CONNECTION_ERROR, this.onError); + this._socket.addEventListener(WebSocketEventEnum.CONNECTION_MESSAGE, this.onMessage); + } + + private destroySocket(): void + { + if(!this._socket) return; + + this._socket.removeEventListener(WebSocketEventEnum.CONNECTION_OPENED, this.onOpen); + this._socket.removeEventListener(WebSocketEventEnum.CONNECTION_CLOSED, this.onClose); + this._socket.removeEventListener(WebSocketEventEnum.CONNECTION_ERROR, this.onError); + this._socket.removeEventListener(WebSocketEventEnum.CONNECTION_MESSAGE, this.onMessage); + + if(this._socket.readyState === WebSocket.OPEN) this._socket.close(); + + this._socket = null; + } + + private onOpen(event: Event): void + { + this.dispatchConnectionEvent(SocketConnectionEvent.CONNECTION_OPENED, event); + } + + private onClose(event: CloseEvent): void + { + this.dispatchConnectionEvent(SocketConnectionEvent.CONNECTION_CLOSED, event); + } + + private onError(event: Event): void + { + this.dispatchConnectionEvent(SocketConnectionEvent.CONNECTION_ERROR, event); + } + + private onMessage(event: MessageEvent): void + { + if(!event) return; + + this.dispatchConnectionEvent(SocketConnectionEvent.CONNECTION_MESSAGE, event); + + const reader = new FileReader(); + + reader.readAsArrayBuffer(event.data); + + reader.onloadend = () => + { + this._dataBuffer = this.concatArrayBuffers(this._dataBuffer, (reader.result as ArrayBuffer)); + + this.processReceivedData(); + }; + } + + private dispatchConnectionEvent(type: string, event: Event): void + { + this.dispatchEvent(new SocketConnectionEvent(type, this, event)); + } + + public authenticated(): void + { + this._isAuthenticated = true; + } + + public send(...composers: IMessageComposer[]): boolean + { + if(this.disposed || !composers) return false; + + composers = [ ...composers ]; + + if(this._isAuthenticated && !this._isReady) + { + if(!this._pendingClientMessages) this._pendingClientMessages = []; + + this._pendingClientMessages.push(...composers); + + return false; + } + + for(const composer of composers) + { + if(!composer) continue; + + const header = this._messages.getComposerId(composer); + + if(header === -1) + { + NitroLogger.log(`Unknown Composer: ${ composer.constructor.name }`); + + continue; + } + + const message = composer.getMessageArray(); + const encoded = this._codec.encode(header, message); + + if(!encoded) + { + if(Nitro.instance.getConfiguration('communication.packet.log')) console.log(`Encoding Failed: ${ composer.constructor.name }`); + + continue; + } + + if(Nitro.instance.getConfiguration('communication.packet.log')) console.log(`OutgoingComposer: [${ header }] ${ composer.constructor.name }`, message); + + this.write(encoded.getBuffer()); + } + + return true; + } + + private write(buffer: ArrayBuffer): void + { + if(this._socket.readyState !== WebSocket.OPEN) return; + + this._socket.send(buffer); + } + + public processReceivedData(): void + { + try + { + this.processData(); + } + + catch (err) + { + NitroLogger.log(err); + } + } + + private processData(): void + { + const wrappers = this.splitReceivedMessages(); + + if(!wrappers || !wrappers.length) return; + + if(this._isAuthenticated && !this._isReady) + { + if(!this._pendingServerMessages) this._pendingServerMessages = []; + + this._pendingServerMessages.push(...wrappers); + + return; + } + + this.processWrappers(...wrappers); + } + + private processWrappers(...wrappers: IMessageDataWrapper[]): void + { + if(!wrappers || !wrappers.length) return; + + for(const wrapper of wrappers) + { + if(!wrapper) continue; + + const messages = this.getMessagesForWrapper(wrapper); + + if(!messages || !messages.length) continue; + + if(Nitro.instance.getConfiguration('communication.packet.log')) + { + console.log(`IncomingMessage: [${ wrapper.header }] ${ messages[0].constructor.name }`, messages[0].parser); + } + + this.handleMessages(...messages); + } + } + + private splitReceivedMessages(): IMessageDataWrapper[] + { + if(!this._dataBuffer || !this._dataBuffer.byteLength) return null; + + return this._codec.decode(this); + } + + private concatArrayBuffers(buffer1: ArrayBuffer, buffer2: ArrayBuffer): ArrayBuffer + { + const array = new Uint8Array(buffer1.byteLength + buffer2.byteLength); + + array.set(new Uint8Array(buffer1), 0); + array.set(new Uint8Array(buffer2), buffer1.byteLength); + + return array.buffer; + } + + private getMessagesForWrapper(wrapper: IMessageDataWrapper): IMessageEvent[] + { + if(!wrapper) return null; + + const events = this._messages.getEvents(wrapper.header); + + if(!events || !events.length) + { + if(Nitro.instance.getConfiguration('communication.packet.log')) + { + console.log(`IncomingMessage: [${ wrapper.header }] UNREGISTERED`, wrapper); + } + + return; + } + + try + { + const parser = events[0].parser; + + if(!parser || !parser.flush() || !parser.parse(wrapper)) return null; + } + + catch (e) + { + NitroLogger.log(`Error parsing message: ${ e }`, events[0].constructor.name); + + return null; + } + + return events; + } + + private handleMessages(...messages: IMessageEvent[]): void + { + messages = [ ...messages ]; + + for(const message of messages) + { + if(!message) continue; + + message.connection = this; + + if(message.callBack) message.callBack(message); + } + } + + public registerMessages(configuration: IMessageConfiguration): void + { + if(!configuration) return; + + this._messages.registerMessages(configuration); + } + + public addMessageEvent(event: IMessageEvent): void + { + if(!event || !this._messages) return; + + this._messages.registerMessageEvent(event); + } + + public removeMessageEvent(event: IMessageEvent): void + { + if(!event || !this._messages) return; + + this._messages.removeMessageEvent(event); + } + + public get isAuthenticated(): boolean + { + return this._isAuthenticated; + } + + public get dataBuffer(): ArrayBuffer + { + return this._dataBuffer; + } + + public set dataBuffer(buffer: ArrayBuffer) + { + this._dataBuffer = buffer; + } +} diff --git a/src/core/communication/connections/enums/ClientDeviceCategoryEnum.ts b/src/core/communication/connections/enums/ClientDeviceCategoryEnum.ts new file mode 100644 index 00000000..01619fef --- /dev/null +++ b/src/core/communication/connections/enums/ClientDeviceCategoryEnum.ts @@ -0,0 +1,5 @@ +export class ClientDeviceCategoryEnum +{ + public static UNKNOWN: number = 0; + public static BROWSER: number = 1; +} \ No newline at end of file diff --git a/src/core/communication/connections/enums/ClientPlatformEnum.ts b/src/core/communication/connections/enums/ClientPlatformEnum.ts new file mode 100644 index 00000000..e74abddd --- /dev/null +++ b/src/core/communication/connections/enums/ClientPlatformEnum.ts @@ -0,0 +1,7 @@ +export class ClientPlatformEnum +{ + public static UNKNOWN: number = 0; + public static FLASH: number = 1; + public static HTML5: number = 2; + +} \ No newline at end of file diff --git a/src/core/communication/connections/enums/WebSocketEventEnum.ts b/src/core/communication/connections/enums/WebSocketEventEnum.ts new file mode 100644 index 00000000..36a3c458 --- /dev/null +++ b/src/core/communication/connections/enums/WebSocketEventEnum.ts @@ -0,0 +1,7 @@ +export class WebSocketEventEnum +{ + public static CONNECTION_OPENED = 'open'; + public static CONNECTION_CLOSED = 'close'; + public static CONNECTION_ERROR = 'error'; + public static CONNECTION_MESSAGE = 'message'; +} \ No newline at end of file diff --git a/src/core/communication/connections/enums/index.ts b/src/core/communication/connections/enums/index.ts new file mode 100644 index 00000000..42a22708 --- /dev/null +++ b/src/core/communication/connections/enums/index.ts @@ -0,0 +1,3 @@ +export * from './ClientDeviceCategoryEnum'; +export * from './ClientPlatformEnum'; +export * from './WebSocketEventEnum'; diff --git a/src/core/communication/connections/index.ts b/src/core/communication/connections/index.ts new file mode 100644 index 00000000..a8e8e168 --- /dev/null +++ b/src/core/communication/connections/index.ts @@ -0,0 +1,4 @@ +export * from './enums'; +export * from './IConnection'; +export * from './IConnectionStateListener'; +export * from './SocketConnection'; diff --git a/src/core/communication/events/SocketConnectionEvent.ts b/src/core/communication/events/SocketConnectionEvent.ts new file mode 100644 index 00000000..51a18fec --- /dev/null +++ b/src/core/communication/events/SocketConnectionEvent.ts @@ -0,0 +1,31 @@ +import { NitroEvent } from '../../events/NitroEvent'; +import { IConnection } from '../connections/IConnection'; + +export class SocketConnectionEvent extends NitroEvent +{ + public static CONNECTION_OPENED = 'SCE_OPEN'; + public static CONNECTION_CLOSED = 'SCE_CLOSED'; + public static CONNECTION_ERROR = 'SCE_ERROR'; + public static CONNECTION_MESSAGE = 'SCE_MESSAGE'; + + private _connection: IConnection; + private _originalEvent: Event; + + constructor(type: string, connection: IConnection, originalEvent: Event) + { + super(type); + + this._connection = connection; + this._originalEvent = event; + } + + public get connection(): IConnection + { + return this._connection; + } + + public get originalEvent(): Event + { + return this._originalEvent; + } +} \ No newline at end of file diff --git a/src/core/communication/events/index.ts b/src/core/communication/events/index.ts new file mode 100644 index 00000000..1093b131 --- /dev/null +++ b/src/core/communication/events/index.ts @@ -0,0 +1 @@ +export * from './SocketConnectionEvent'; diff --git a/src/core/communication/index.ts b/src/core/communication/index.ts new file mode 100644 index 00000000..b34d744e --- /dev/null +++ b/src/core/communication/index.ts @@ -0,0 +1,6 @@ +export * from './codec'; +export * from './CommunicationManager'; +export * from './connections'; +export * from './events'; +export * from './ICommunicationManager'; +export * from './messages'; diff --git a/src/core/communication/messages/IMessageComposer.ts b/src/core/communication/messages/IMessageComposer.ts new file mode 100644 index 00000000..eb09bc82 --- /dev/null +++ b/src/core/communication/messages/IMessageComposer.ts @@ -0,0 +1,5 @@ +export interface IMessageComposer +{ + dispose(): void; + getMessageArray(): T; +} \ No newline at end of file diff --git a/src/core/communication/messages/IMessageConfiguration.ts b/src/core/communication/messages/IMessageConfiguration.ts new file mode 100644 index 00000000..03efd30a --- /dev/null +++ b/src/core/communication/messages/IMessageConfiguration.ts @@ -0,0 +1,5 @@ +export interface IMessageConfiguration +{ + events: Map; + composers: Map; +} \ No newline at end of file diff --git a/src/core/communication/messages/IMessageDataWrapper.ts b/src/core/communication/messages/IMessageDataWrapper.ts new file mode 100644 index 00000000..0623d859 --- /dev/null +++ b/src/core/communication/messages/IMessageDataWrapper.ts @@ -0,0 +1,13 @@ +import { BinaryReader } from '../codec/BinaryReader'; + +export interface IMessageDataWrapper +{ + readByte(): number; + readBytes(length: number): BinaryReader; + readBoolean(): boolean; + readShort(): number; + readInt(): number; + readString(): string; + header: number; + bytesAvailable: boolean; +} \ No newline at end of file diff --git a/src/core/communication/messages/IMessageEvent.ts b/src/core/communication/messages/IMessageEvent.ts new file mode 100644 index 00000000..58b802d9 --- /dev/null +++ b/src/core/communication/messages/IMessageEvent.ts @@ -0,0 +1,11 @@ +import { IConnection } from '../connections/IConnection'; +import { IMessageParser } from './IMessageParser'; + +export interface IMessageEvent +{ + dispose(): void; + callBack: Function; + parserClass: Function; + parser: IMessageParser; + connection: IConnection; +} \ No newline at end of file diff --git a/src/core/communication/messages/IMessageParser.ts b/src/core/communication/messages/IMessageParser.ts new file mode 100644 index 00000000..f10a50d5 --- /dev/null +++ b/src/core/communication/messages/IMessageParser.ts @@ -0,0 +1,7 @@ +import { IMessageDataWrapper } from './IMessageDataWrapper'; + +export interface IMessageParser +{ + flush(): boolean; + parse(wrapper: IMessageDataWrapper): boolean; +} \ No newline at end of file diff --git a/src/core/communication/messages/MessageClassManager.ts b/src/core/communication/messages/MessageClassManager.ts new file mode 100644 index 00000000..c5dbdb0d --- /dev/null +++ b/src/core/communication/messages/MessageClassManager.ts @@ -0,0 +1,145 @@ +import { IMessageComposer } from './IMessageComposer'; +import { IMessageConfiguration } from './IMessageConfiguration'; +import { IMessageEvent } from './IMessageEvent'; +import { MessageEvent } from './MessageEvent'; + +export class MessageClassManager +{ + private _messageIdByEvent: Map; + private _messageIdByComposer: Map; + private _messageInstancesById: Map; + + constructor() + { + this._messageIdByEvent = new Map(); + this._messageIdByComposer = new Map(); + this._messageInstancesById = new Map(); + } + + public dispose(): void + { + this._messageIdByEvent.clear(); + this._messageIdByComposer.clear(); + this._messageInstancesById.clear(); + } + + public registerMessages(configuration: IMessageConfiguration): void + { + for(const [ header, handler ] of configuration.events) this.registerMessageEventClass(header, handler); + + for(const [ header, handler ] of configuration.composers) this.registerMessageComposerClass(header, handler); + } + + private registerMessageEventClass(header: number, handler: Function): void + { + if(!header || !handler) return; + + const existing = this._messageIdByEvent.get(handler); + + if(existing) return; + + this._messageIdByEvent.set(handler, header); + } + + private registerMessageComposerClass(header: number, handler: Function): void + { + if(!header || !handler) return; + + const existing = this._messageIdByComposer.get(handler); + + if(existing) return; + + this._messageIdByComposer.set(handler, header); + } + + public registerMessageEvent(event: IMessageEvent): void + { + if(!event) return; + + const header = this.getEventId(event); + + if(!header) return; + + let existing = this._messageInstancesById.get(header); + + if(!existing || !existing.length) + { + existing = []; + + this._messageInstancesById.set(header, existing); + + //@ts-ignore + event.parser = new event.parserClass(); + } + else + { + event.parser = existing[0].parser; + } + + existing.push(event); + } + + public removeMessageEvent(event: IMessageEvent): void + { + if(!event) return; + + const header = this.getEventId(event); + + if(!header) return; + + const existing = this._messageInstancesById.get(header); + + if(!existing) return; + + for(const [ index, message ] of existing.entries()) + { + if(!message) continue; + + if(message !== event) continue; + + existing.splice(index, 1); + + if(existing.length === 0) this._messageInstancesById.delete(header); + + message.dispose(); + + return; + } + } + + public getEvents(header: number): IMessageEvent[] + { + if(!header) return; + + const existing = this._messageInstancesById.get(header); + + if(!existing) return; + + return existing; + } + + public getEventId(event: IMessageEvent): number + { + if(!event) return -1; + + //@ts-ignore + const name = (event instanceof MessageEvent ? event.constructor : event) as Function; + + const existing = this._messageIdByEvent.get(name); + + if(!existing) return -1; + + return existing; + } + + public getComposerId(composer: IMessageComposer): number + { + if(!composer) return -1; + + const existing = this._messageIdByComposer.get(composer.constructor); + + if(!existing) return -1; + + return existing; + } +} diff --git a/src/core/communication/messages/MessageEvent.ts b/src/core/communication/messages/MessageEvent.ts new file mode 100644 index 00000000..0c66b659 --- /dev/null +++ b/src/core/communication/messages/MessageEvent.ts @@ -0,0 +1,57 @@ +import { IConnection } from '../connections/IConnection'; +import { IMessageEvent } from './IMessageEvent'; +import { IMessageParser } from './IMessageParser'; + +export class MessageEvent implements IMessageEvent +{ + private _callBack: Function; + private _parserClass: Function; + private _parser: IMessageParser; + private _connection: IConnection; + + constructor(callBack: Function, parser: { new(): IMessageParser }) + { + this._callBack = callBack; + this._parserClass = parser; + this._parser = null; + this._connection = null; + } + + public dispose(): void + { + this._callBack = null; + this._parserClass = null; + this._parser = null; + this._connection = null; + } + + public get callBack(): Function + { + return this._callBack; + } + + public get parserClass(): Function + { + return this._parserClass; + } + + public get parser(): IMessageParser + { + return this._parser; + } + + public set parser(parser: IMessageParser) + { + this._parser = parser; + } + + public get connection(): IConnection + { + return this._connection; + } + + public set connection(connection: IConnection) + { + this._connection = connection; + } +} \ No newline at end of file diff --git a/src/core/communication/messages/index.ts b/src/core/communication/messages/index.ts new file mode 100644 index 00000000..5cc8eb81 --- /dev/null +++ b/src/core/communication/messages/index.ts @@ -0,0 +1,7 @@ +export * from './IMessageComposer'; +export * from './IMessageConfiguration'; +export * from './IMessageDataWrapper'; +export * from './IMessageEvent'; +export * from './IMessageParser'; +export * from './MessageClassManager'; +export * from './MessageEvent'; diff --git a/src/core/configuration/ConfigurationEvent.ts b/src/core/configuration/ConfigurationEvent.ts new file mode 100644 index 00000000..959fa8e4 --- /dev/null +++ b/src/core/configuration/ConfigurationEvent.ts @@ -0,0 +1,12 @@ +import { NitroEvent } from '../events/NitroEvent'; + +export class ConfigurationEvent extends NitroEvent +{ + public static LOADED: string = 'NCE_LOADED'; + public static FAILED: string = 'NCE_FAILED'; + + constructor(type: string) + { + super(type); + } +} \ No newline at end of file diff --git a/src/core/configuration/ConfigurationManager.ts b/src/core/configuration/ConfigurationManager.ts new file mode 100644 index 00000000..bcd93c31 --- /dev/null +++ b/src/core/configuration/ConfigurationManager.ts @@ -0,0 +1,137 @@ +import { NitroManager } from '../common/NitroManager'; +import { AdvancedMap } from '../utils/AdvancedMap'; +import { ConfigurationEvent } from './ConfigurationEvent'; +import { IConfigurationManager } from './IConfigurationManager'; + +export class ConfigurationManager extends NitroManager implements IConfigurationManager +{ + private _definitions: AdvancedMap; + + constructor() + { + super(); + + this._definitions = new AdvancedMap(); + + this.onConfigurationLoaded = this.onConfigurationLoaded.bind(this); + } + + protected onInit(): void + { + //@ts-ignore + this.loadConfigurationFromUrl(NitroConfig.configurationUrl); + } + + public loadConfigurationFromUrl(url: string): void + { + if(!url || (url === '')) + { + this.dispatchConfigurationEvent(ConfigurationEvent.FAILED); + + return; + } + + fetch(url) + .then(response => response.json()) + .then(data => this.onConfigurationLoaded(data)) + .catch(err => this.onConfigurationFailed(err)); + } + + private onConfigurationLoaded(data: { [index: string]: any }): void + { + if(!data) return; + + if(this.parseConfiguration(data)) + { + this.dispatchConfigurationEvent(ConfigurationEvent.LOADED); + + return; + } + + this.dispatchConfigurationEvent(ConfigurationEvent.FAILED); + } + + private onConfigurationFailed(error: Error): void + { + this.dispatchConfigurationEvent(ConfigurationEvent.FAILED); + } + + private dispatchConfigurationEvent(type: string): void + { + this.events && this.events.dispatchEvent(new ConfigurationEvent(type)); + } + + private parseConfiguration(data: { [index: string]: any }): boolean + { + if(!data) return false; + + try + { + const regex = new RegExp(/\${(.*?)}/g); + + for(const key in data) + { + let value = data[key]; + + if(typeof value === 'string') + { + value = this.interpolate((value as string), regex); + } + + this._definitions.add(key, value); + } + + return true; + } + + catch (e) + { + this.logger.error(e.stack); + + return false; + } + } + + public interpolate(value: string, regex: RegExp = null): string + { + if(!regex) regex = new RegExp(/\${(.*?)}/g); + + const pieces = value.match(regex); + + if(pieces && pieces.length) + { + for(const piece of pieces) + { + const existing = (this._definitions.getValue(this.removeInterpolateKey(piece)) as string); + + if(existing) (value = value.replace(piece, existing)); + } + } + + return value; + } + + private removeInterpolateKey(value: string): string + { + return value.replace('${', '').replace('}', ''); + } + + public getValue(key: string, value: T = null): T + { + let existing = this._definitions.getValue(key); + + if(existing === undefined) + { + this.logger.warn(`Missing configuration key: ${ key }`); + + existing = value; + } + + return (existing as T); + } + + public setValue(key: string, value: string): void + { + this._definitions.add(key, value); + } +} diff --git a/src/core/configuration/IConfigurationManager.ts b/src/core/configuration/IConfigurationManager.ts new file mode 100644 index 00000000..1d18a8f4 --- /dev/null +++ b/src/core/configuration/IConfigurationManager.ts @@ -0,0 +1,8 @@ +import { INitroManager } from '../common/INitroManager'; + +export interface IConfigurationManager extends INitroManager +{ + interpolate(value: string, regex?: RegExp): string; + getValue(key: string, value?: T): T; + setValue(key: string, value: string): void; +} \ No newline at end of file diff --git a/src/core/configuration/index.ts b/src/core/configuration/index.ts new file mode 100644 index 00000000..cac646dd --- /dev/null +++ b/src/core/configuration/index.ts @@ -0,0 +1,3 @@ +export * from './ConfigurationEvent'; +export * from './ConfigurationManager'; +export * from './IConfigurationManager'; diff --git a/src/core/events/EventDispatcher.ts b/src/core/events/EventDispatcher.ts new file mode 100644 index 00000000..773e7c68 --- /dev/null +++ b/src/core/events/EventDispatcher.ts @@ -0,0 +1,112 @@ +import { Nitro } from '../../nitro/Nitro'; +import { Disposable } from '../common/disposable/Disposable'; +import { IDisposable } from '../common/disposable/IDisposable'; +import { INitroLogger } from '../common/logger/INitroLogger'; +import { NitroLogger } from '../common/logger/NitroLogger'; +import { IEventDispatcher } from './IEventDispatcher'; + +export class EventDispatcher extends Disposable implements IEventDispatcher, IDisposable +{ + private _logger: INitroLogger; + private _listeners: Map; + + constructor() + { + super(); + + this._logger = new NitroLogger(this.constructor.name); + this._listeners = new Map(); + } + + protected onDispose(): void + { + this.removeAllListeners(); + + super.onDispose(); + } + + public addEventListener(type: string, callback: Function): void + { + if(!type || !callback) return; + + const existing = this._listeners.get(type); + + if(!existing) + { + this._listeners.set(type, [ callback ]); + + return; + } + + existing.push(callback); + } + + public removeEventListener(type: string, callback: any): void + { + if(!type || !callback) return; + + const existing = this._listeners.get(type); + + if(!existing || !existing.length) return; + + for(const [ i, cb ] of existing.entries()) + { + if(!cb || (cb !== callback)) continue; + + existing.splice(i, 1); + + if(!existing.length) this._listeners.delete(type); + + return; + } + } + + public dispatchEvent(event: Event): boolean + { + if(!event) return false; + + if(Nitro.instance.getConfiguration('system.dispatcher.log')) this._logger.log(`DISPATCHED: ${ event.type }`); + + this.processEvent(event); + + return true; + } + + private processEvent(event: Event): void + { + const existing = this._listeners.get(event.type); + + if(!existing || !existing.length) return; + + const callbacks = []; + + for(const callback of existing) + { + if(!callback) continue; + + callbacks.push(callback); + } + + while(callbacks.length) + { + const callback = callbacks.shift(); + + try + { + callback(event); + } + + catch (err) + { + this._logger.error(err.stack); + + return; + } + } + } + + public removeAllListeners(): void + { + this._listeners.clear(); + } +} diff --git a/src/core/events/IEventDispatcher.ts b/src/core/events/IEventDispatcher.ts new file mode 100644 index 00000000..50a6019a --- /dev/null +++ b/src/core/events/IEventDispatcher.ts @@ -0,0 +1,9 @@ +import { IDisposable } from '../common/disposable/IDisposable'; + +export interface IEventDispatcher extends IDisposable +{ + addEventListener(type: string, callback: Function): void + removeEventListener(type: string, callback: Function): void; + removeAllListeners(): void; + dispatchEvent(event: Event): boolean; +} \ No newline at end of file diff --git a/src/core/events/ILinkEventTracker.ts b/src/core/events/ILinkEventTracker.ts new file mode 100644 index 00000000..311567d0 --- /dev/null +++ b/src/core/events/ILinkEventTracker.ts @@ -0,0 +1,5 @@ +export interface ILinkEventTracker +{ + linkReceived(link: string): void; + eventUrlPrefix: string; +} \ No newline at end of file diff --git a/src/core/events/IWorkerEventTracker.ts b/src/core/events/IWorkerEventTracker.ts new file mode 100644 index 00000000..cde3c203 --- /dev/null +++ b/src/core/events/IWorkerEventTracker.ts @@ -0,0 +1,4 @@ +export interface IWorkerEventTracker +{ + workerMessageReceived(message: { [index: string]: any }): void; +} diff --git a/src/core/events/NitroEvent.ts b/src/core/events/NitroEvent.ts new file mode 100644 index 00000000..f6d3743a --- /dev/null +++ b/src/core/events/NitroEvent.ts @@ -0,0 +1,4 @@ +export class NitroEvent extends Event +{ + public static COMPLETE: string = 'NITRO_COMPLETE'; +} \ No newline at end of file diff --git a/src/core/events/index.ts b/src/core/events/index.ts new file mode 100644 index 00000000..17a287bc --- /dev/null +++ b/src/core/events/index.ts @@ -0,0 +1,5 @@ +export * from './EventDispatcher'; +export * from './IEventDispatcher'; +export * from './ILinkEventTracker'; +export * from './IWorkerEventTracker'; +export * from './NitroEvent'; diff --git a/src/core/index.ts b/src/core/index.ts new file mode 100644 index 00000000..3fbcc8d6 --- /dev/null +++ b/src/core/index.ts @@ -0,0 +1,8 @@ +export * from './asset'; +export * from './common'; +export * from './communication'; +export * from './configuration'; +export * from './events'; +export * from './INitroCore'; +export * from './NitroCore'; +export * from './utils'; diff --git a/src/core/utils/AdvancedMap.ts b/src/core/utils/AdvancedMap.ts new file mode 100644 index 00000000..4683d487 --- /dev/null +++ b/src/core/utils/AdvancedMap.ts @@ -0,0 +1,157 @@ +import { IDisposable } from '../common/disposable/IDisposable'; + +export class AdvancedMap implements IDisposable +{ + private _length: number; + private _dictionary: Map; + private _array: U[]; + private _keys: T[]; + + constructor() + { + this._length = 0; + this._dictionary = new Map(); + this._array = []; + this._keys = []; + } + + public get length(): number + { + return this._length; + } + + public get disposed(): boolean + { + return (!this._dictionary); + } + + public dispose(): void + { + if(!this._dictionary) + { + for(const key of this._dictionary.keys()) this._dictionary.delete(key); + + this._dictionary = null; + } + + this._length = 0; + this._array = null; + this._keys = null; + } + + public reset(): void + { + for(const key of this._dictionary.keys()) this._dictionary.delete(key); + + this._length = 0; + this._array = []; + this._keys = []; + } + + public unshift(key: T, value: U): boolean + { + if(this._dictionary.get(key) !== null) return false; + + this._dictionary.set(key, value); + + this._array.unshift(value); + this._keys.unshift(key); + + this._length++; + + return true; + } + + public add(key: T, value: U): boolean + { + if(this._dictionary.get(key) !== undefined) return false; + + this._dictionary.set(key, value); + + this._array[this._length] = value; + this._keys[this._length] = key; + + this._length++; + + return true; + } + + public remove(key: T): U + { + const value = this._dictionary.get(key); + + if(!value) return null; + + const index = this._array.indexOf(value); + + if(index >= 0) + { + this._array.splice(index, 1); + this._keys.splice(index, 1); + + this._length--; + } + + this._dictionary.delete(key); + + return value; + } + + public getWithIndex(index: number): U + { + if((index < 0) || (index >= this._length)) return null; + + return this._array[index]; + } + + public getKey(index: number): T + { + if((index < 0) || (index >= this._length)) return null; + + return this._keys[index]; + } + + public getKeys(): T[] + { + return this._keys.slice(); + } + + public hasKey(key: T): boolean + { + return (this._keys.indexOf(key) > -1); + } + + public getValue(key: T): U + { + return this._dictionary.get(key); + } + + public getValues(): U[] + { + return this._array.slice(); + } + + public hasValue(value: U): boolean + { + return (this._array.indexOf(value) > -1); + } + + public indexOf(value: U): number + { + return this._array.indexOf(value); + } + + public concatenate(newValues: AdvancedMap): void + { + for(const k of newValues._keys) this.add(k, newValues.getValue(k)); + } + + public clone(): AdvancedMap + { + const map = new AdvancedMap(); + + map.concatenate(this); + + return map; + } +} \ No newline at end of file diff --git a/src/core/utils/NitroTimer.ts b/src/core/utils/NitroTimer.ts new file mode 100644 index 00000000..3cf960c7 --- /dev/null +++ b/src/core/utils/NitroTimer.ts @@ -0,0 +1,43 @@ +export class NitroTimer +{ + private _elapsedTime: number; + private _percision: number; + private _timer: any; + + constructor(percision: number = 1) + { + this._elapsedTime = 0; + this._percision = percision; + this._timer = null; + + this.start(); + } + + public start(): void + { + this._elapsedTime = 0; + + if(!this._timer) + { + this._timer = setInterval(() => this.increase(), this._percision); + } + } + + public stop(): void + { + if(this._timer) + { + clearTimeout(this._timer); + } + } + + private increase(): void + { + this._elapsedTime += this._percision; + } + + public getTimer(): number + { + return this._elapsedTime; + } +} \ No newline at end of file diff --git a/src/core/utils/index.ts b/src/core/utils/index.ts new file mode 100644 index 00000000..0eb447c2 --- /dev/null +++ b/src/core/utils/index.ts @@ -0,0 +1,2 @@ +export * from './AdvancedMap'; +export * from './NitroTimer'; diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 00000000..4b0e0413 --- /dev/null +++ b/src/index.ts @@ -0,0 +1 @@ +export * from './core'; diff --git a/src/nitro/INitro.ts b/src/nitro/INitro.ts new file mode 100644 index 00000000..5f1009c1 --- /dev/null +++ b/src/nitro/INitro.ts @@ -0,0 +1,45 @@ +import { Application } from 'pixi.js'; +import { IEventDispatcher } from '../core/events/IEventDispatcher'; +import { ILinkEventTracker } from '../core/events/ILinkEventTracker'; +import { IWorkerEventTracker } from '../core/events/IWorkerEventTracker'; +import { INitroCore } from '../core/INitroCore'; +import { NitroTimer } from '../core/utils/NitroTimer'; +import { IRoomManager } from '../room/IRoomManager'; +import { IAvatarRenderManager } from './avatar/IAvatarRenderManager'; +import { INitroCommunicationManager } from './communication/INitroCommunicationManager'; +import { INitroLocalizationManager } from './localization/INitroLocalizationManager'; +import { IRoomEngine } from './room/IRoomEngine'; +import { IRoomSessionManager } from './session/IRoomSessionManager'; +import { ISessionDataManager } from './session/ISessionDataManager'; + +export interface INitro extends Application +{ + init(): void; + dispose(): void; + getConfiguration(key: string, value?: T): T; + getLocalization(key: string): string; + getLocalizationWithParameter(key: string, parameter: string, replacement: string): string; + getLocalizationWithParameters(key: string, parameters: string[], replacements: string[]): string; + addWorkerEventTracker(tracker: IWorkerEventTracker): void; + removeWorkerEventTracker(tracker: IWorkerEventTracker): void; + createWorkerEvent(message: { [index: string]: any }): void; + sendWorkerEvent(message: { [index: string]: any }): void; + addLinkEventTracker(tracker: ILinkEventTracker): void; + removeLinkEventTracker(tracker: ILinkEventTracker): void; + createLinkEvent(link: string): void; + nitroTimer: NitroTimer; + core: INitroCore; + events: IEventDispatcher; + localization: INitroLocalizationManager; + communication: INitroCommunicationManager; + avatar: IAvatarRenderManager; + roomEngine: IRoomEngine; + sessionDataManager: ISessionDataManager; + roomSessionManager: IRoomSessionManager; + roomManager: IRoomManager; + width: number; + height: number; + time: number; + isReady: boolean; + isDisposed: boolean; +} diff --git a/src/nitro/Nitro.ts b/src/nitro/Nitro.ts new file mode 100644 index 00000000..053fd75e --- /dev/null +++ b/src/nitro/Nitro.ts @@ -0,0 +1,417 @@ +import { Application, SCALE_MODES, settings } from 'pixi.js'; +import { ConfigurationEvent } from '../core/configuration/ConfigurationEvent'; +import { EventDispatcher } from '../core/events/EventDispatcher'; +import { IEventDispatcher } from '../core/events/IEventDispatcher'; +import { ILinkEventTracker } from '../core/events/ILinkEventTracker'; +import { IWorkerEventTracker } from '../core/events/IWorkerEventTracker'; +import { NitroEvent } from '../core/events/NitroEvent'; +import { INitroCore } from '../core/INitroCore'; +import { NitroCore } from '../core/NitroCore'; +import { NitroTimer } from '../core/utils/NitroTimer'; +import { IRoomManager } from '../room/IRoomManager'; +import { RoomManager } from '../room/RoomManager'; +import { AvatarRenderManager } from './avatar/AvatarRenderManager'; +import { IAvatarRenderManager } from './avatar/IAvatarRenderManager'; +import { INitroCommunicationManager } from './communication/INitroCommunicationManager'; +import { NitroCommunicationManager } from './communication/NitroCommunicationManager'; +import { LegacyExternalInterface } from './externalInterface/LegacyExternalInterface'; +import { GameMessageHandler } from './game/GameMessageHandler'; +import { INitro } from './INitro'; +import { INitroLocalizationManager } from './localization/INitroLocalizationManager'; +import { NitroLocalizationManager } from './localization/NitroLocalizationManager'; +import { RoomEngineEvent } from './room/events/RoomEngineEvent'; +import { IRoomEngine } from './room/IRoomEngine'; +import { RoomEngine } from './room/RoomEngine'; +import { IRoomSessionManager } from './session/IRoomSessionManager'; +import { ISessionDataManager } from './session/ISessionDataManager'; +import { RoomSessionManager } from './session/RoomSessionManager'; +import { SessionDataManager } from './session/SessionDataManager'; +import { HabboWebTools } from './utils/HabboWebTools'; + +LegacyExternalInterface.available; + +settings.FAIL_IF_MAJOR_PERFORMANCE_CAVEAT = false; +settings.SCALE_MODE = SCALE_MODES.NEAREST; + +export class Nitro extends Application implements INitro +{ + public static WEBGL_CONTEXT_LOST: string = 'NE_WEBGL_CONTEXT_LOST'; + public static WEBGL_UNAVAILABLE: string = 'NE_WEBGL_UNAVAILABLE'; + public static RELEASE_VERSION: string = 'NITRO-0-4-0'; + public static READY: string = 'NE_READY'; + + private static INSTANCE: INitro = null; + + private _nitroTimer: NitroTimer; + private _worker: Worker; + private _core: INitroCore; + private _events: IEventDispatcher; + private _localization: INitroLocalizationManager; + private _communication: INitroCommunicationManager; + private _avatar: IAvatarRenderManager; + private _roomEngine: IRoomEngine; + private _sessionDataManager: ISessionDataManager; + private _roomSessionManager: IRoomSessionManager; + private _roomManager: IRoomManager; + private _linkTrackers: ILinkEventTracker[]; + private _workerTrackers: IWorkerEventTracker[]; + + private _isReady: boolean; + private _isDisposed: boolean; + + constructor(core: INitroCore, options?: { + autoStart?: boolean; + width?: number; + height?: number; + view?: HTMLCanvasElement; + transparent?: boolean; + autoDensity?: boolean; + antialias?: boolean; + preserveDrawingBuffer?: boolean; + resolution?: number; + forceCanvas?: boolean; + backgroundColor?: number; + clearBeforeRender?: boolean; + powerPreference?: string; + sharedTicker?: boolean; + sharedLoader?: boolean; + resizeTo?: Window | HTMLElement; + }) + { + super(options); + + if(!Nitro.INSTANCE) Nitro.INSTANCE = this; + + this._nitroTimer = new NitroTimer(); + this._worker = new Worker('../nitro-worker.worker', { type: 'module' }); + this._core = core; + this._events = new EventDispatcher(); + this._localization = new NitroLocalizationManager(); + this._communication = new NitroCommunicationManager(core.communication); + this._avatar = new AvatarRenderManager(); + this._roomEngine = new RoomEngine(this._communication); + this._sessionDataManager = new SessionDataManager(this._communication); + this._roomSessionManager = new RoomSessionManager(this._communication, this._roomEngine); + this._roomManager = new RoomManager(this._roomEngine, this._roomEngine.visualizationFactory, this._roomEngine.logicFactory); + this._linkTrackers = []; + this._workerTrackers = []; + + this._isReady = false; + this._isDisposed = false; + + this._core.configuration.events.addEventListener(ConfigurationEvent.LOADED, this.onConfigurationLoadedEvent.bind(this)); + this._roomEngine.events.addEventListener(RoomEngineEvent.ENGINE_INITIALIZED, this.onRoomEngineReady.bind(this)); + + this._worker.onmessage = this.createWorkerEvent.bind(this); + } + + public static bootstrap(): void + { + if(Nitro.INSTANCE) + { + Nitro.INSTANCE.dispose(); + + Nitro.INSTANCE = null; + } + + const canvas = document.createElement('canvas'); + + canvas.id = 'client-wrapper'; + canvas.className = 'client-canvas'; + + const instance = new this(new NitroCore(), { + transparent: true, + autoDensity: true, + resolution: window.devicePixelRatio, + width: window.innerWidth, + height: window.innerHeight, + view: canvas + }); + + canvas.addEventListener('webglcontextlost', () => instance.events.dispatchEvent(new NitroEvent(Nitro.WEBGL_CONTEXT_LOST))); + + //@ts-ignore + const sso = (NitroConfig.sso as string); + + instance.communication.demo.setSSO(sso); + } + + public init(): void + { + if(this._isReady || this._isDisposed) return; + + if(this._avatar) this._avatar.init(); + + if(this._roomEngine) + { + this._roomEngine.sessionDataManager = this._sessionDataManager; + this._roomEngine.roomSessionManager = this._roomSessionManager; + this._roomEngine.roomManager = this._roomManager; + + if(this._sessionDataManager) this._sessionDataManager.init(); + if(this._roomSessionManager) this._roomSessionManager.init(); + + this._roomEngine.init(); + } + + new GameMessageHandler(this._communication.connection); + + if(!this._communication.connection) + { + throw new Error('No connection found'); + } + + this._isReady = true; + } + + public dispose(): void + { + if(this._isDisposed) return; + + if(this._roomManager) + { + this._roomManager.dispose(); + + this._roomManager = null; + } + + if(this._roomSessionManager) + { + this._roomSessionManager.dispose(); + + this._roomSessionManager = null; + } + + if(this._sessionDataManager) + { + this._sessionDataManager.dispose(); + + this._sessionDataManager = null; + } + + if(this._roomEngine) + { + this._roomEngine.dispose(); + + this._roomEngine = null; + } + + if(this._avatar) + { + this._avatar.dispose(); + + this._avatar = null; + } + + if(this._communication) + { + this._communication.dispose(); + + this._communication = null; + } + + super.destroy(); + + this._isDisposed = true; + this._isReady = false; + } + + private onConfigurationLoadedEvent(event: ConfigurationEvent): void + { + const animationFPS = this.getConfiguration('animation.fps', 24); + const limitsFPS = this.getConfiguration('limits.fps', true); + + Nitro.instance.ticker.maxFPS = animationFPS; + } + + private onRoomEngineReady(event: RoomEngineEvent): void + { + this.startSendingHeartBeat(); + } + + public getConfiguration(key: string, value: T = null): T + { + return this._core.configuration.getValue(key, value); + } + + public getLocalization(key: string): string + { + return this._localization.getValue(key); + } + + public getLocalizationWithParameter(key: string, parameter: string, replacement: string): string + { + return this._localization.getValueWithParameter(key, parameter, replacement); + } + + public getLocalizationWithParameters(key: string, parameters: string[], replacements: string[]): string + { + return this._localization.getValueWithParameters(key, parameters, replacements); + } + + public addWorkerEventTracker(tracker: IWorkerEventTracker): void + { + if(this._workerTrackers.indexOf(tracker) >= 0) return; + + this._workerTrackers.push(tracker); + } + + public removeWorkerEventTracker(tracker: IWorkerEventTracker): void + { + const index = this._workerTrackers.indexOf(tracker); + + if(index === -1) return; + + this._workerTrackers.splice(index, 1); + } + + public createWorkerEvent(message: MessageEvent): void + { + if(!message) return; + + const data: { [index: string]: any } = message.data; + + for(const tracker of this._workerTrackers) + { + if(!tracker) continue; + + tracker.workerMessageReceived(data); + } + } + + public sendWorkerEvent(message: { [index: string]: any }): void + { + if(!message || !this._worker) return; + + this._worker.postMessage(message); + } + + public addLinkEventTracker(tracker: ILinkEventTracker): void + { + if(this._linkTrackers.indexOf(tracker) >= 0) return; + + this._linkTrackers.push(tracker); + } + + public removeLinkEventTracker(tracker: ILinkEventTracker): void + { + const index = this._linkTrackers.indexOf(tracker); + + if(index === -1) return; + + this._linkTrackers.splice(index, 1); + } + + public createLinkEvent(link: string): void + { + if(!link || (link === '')) return; + + for(const tracker of this._linkTrackers) + { + if(!tracker) continue; + + const prefix = tracker.eventUrlPrefix; + + if(prefix.length > 0) + { + if(link.substr(0, prefix.length) === prefix) tracker.linkReceived(link); + } + else + { + tracker.linkReceived(link); + } + } + } + + private startSendingHeartBeat(): void + { + this.sendHeartBeat(); + + setInterval(this.sendHeartBeat, 10000); + } + + private sendHeartBeat(): void + { + HabboWebTools.sendHeartBeat(); + } + + public get nitroTimer(): NitroTimer + { + return this._nitroTimer; + } + + public get core(): INitroCore + { + return this._core; + } + + public get events(): IEventDispatcher + { + return this._events; + } + + public get localization(): INitroLocalizationManager + { + return this._localization; + } + + public get communication(): INitroCommunicationManager + { + return this._communication; + } + + public get avatar(): IAvatarRenderManager + { + return this._avatar; + } + + public get roomEngine(): IRoomEngine + { + return this._roomEngine; + } + + public get sessionDataManager(): ISessionDataManager + { + return this._sessionDataManager; + } + + public get roomSessionManager(): IRoomSessionManager + { + return this._roomSessionManager; + } + + public get roomManager(): IRoomManager + { + return this._roomManager; + } + + public get width(): number + { + return (this.renderer.width / this.renderer.resolution); + } + + public get height(): number + { + return (this.renderer.height / this.renderer.resolution); + } + + public get time(): number + { + return this.ticker.lastTime; + } + + public get isReady(): boolean + { + return this._isReady; + } + + public get isDisposed(): boolean + { + return this._isDisposed; + } + + public static get instance(): INitro + { + return this.INSTANCE || null; + } +} diff --git a/src/nitro/avatar/AvatarAssetDownloadLibrary.ts b/src/nitro/avatar/AvatarAssetDownloadLibrary.ts new file mode 100644 index 00000000..76a72914 --- /dev/null +++ b/src/nitro/avatar/AvatarAssetDownloadLibrary.ts @@ -0,0 +1,74 @@ +import { IAssetManager } from '../../core/asset/IAssetManager'; +import { EventDispatcher } from '../../core/events/EventDispatcher'; +import { AvatarRenderLibraryEvent } from './events/AvatarRenderLibraryEvent'; + +export class AvatarAssetDownloadLibrary extends EventDispatcher +{ + public static DOWNLOAD_COMPLETE: string = 'AADL_DOWNLOAD_COMPLETE'; + + private static NOT_LOADED: number = 0; + private static LOADING: number = 1; + private static LOADED: number = 2; + + private _state: number; + private _libraryName: string; + private _revision: string; + private _downloadUrl: string; + private _assets: IAssetManager; + + constructor(id: string, revision: string, assets: IAssetManager, assetUrl: string) + { + super(); + + this._state = AvatarAssetDownloadLibrary.NOT_LOADED; + this._libraryName = id; + this._revision = revision; + this._downloadUrl = assetUrl; + this._assets = assets; + + this._downloadUrl = this._downloadUrl.replace(/%libname%/gi, this._libraryName); + this._downloadUrl = this._downloadUrl.replace(/%revision%/gi, this._revision); + + const asset = this._assets.getCollection(this._libraryName); + + if(asset) this._state = AvatarAssetDownloadLibrary.LOADED; + } + + public downloadAsset(): void + { + if(!this._assets || (this._state === AvatarAssetDownloadLibrary.LOADING) || (this._state === AvatarAssetDownloadLibrary.LOADED)) return; + + const asset = this._assets.getCollection(this._libraryName); + + if(asset) + { + this._state = AvatarAssetDownloadLibrary.LOADED; + + this.dispatchEvent(new AvatarRenderLibraryEvent(AvatarRenderLibraryEvent.DOWNLOAD_COMPLETE, this)); + + return; + } + + this._state = AvatarAssetDownloadLibrary.LOADING; + + this._assets.downloadAsset(this._downloadUrl, (flag: boolean) => + { + if(flag) + { + this._state = AvatarAssetDownloadLibrary.LOADED; + + this.dispatchEvent(new AvatarRenderLibraryEvent(AvatarRenderLibraryEvent.DOWNLOAD_COMPLETE, this)); + } + }); + } + + public get libraryName(): string + { + return this._libraryName; + } + + public get isLoaded(): boolean + { + return (this._state === AvatarAssetDownloadLibrary.LOADED); + } +} \ No newline at end of file diff --git a/src/nitro/avatar/AvatarAssetDownloadManager.ts b/src/nitro/avatar/AvatarAssetDownloadManager.ts new file mode 100644 index 00000000..c69d75ee --- /dev/null +++ b/src/nitro/avatar/AvatarAssetDownloadManager.ts @@ -0,0 +1,343 @@ +import { IAssetManager } from '../../core/asset/IAssetManager'; +import { NitroLogger } from '../../core/common/logger/NitroLogger'; +import { EventDispatcher } from '../../core/events/EventDispatcher'; +import { NitroEvent } from '../../core/events/NitroEvent'; +import { Nitro } from '../Nitro'; +import { AvatarAssetDownloadLibrary } from './AvatarAssetDownloadLibrary'; +import { AvatarStructure } from './AvatarStructure'; +import { AvatarRenderEvent } from './events/AvatarRenderEvent'; +import { AvatarRenderLibraryEvent } from './events/AvatarRenderLibraryEvent'; +import { IAvatarFigureContainer } from './IAvatarFigureContainer'; +import { IAvatarImageListener } from './IAvatarImageListener'; + +export class AvatarAssetDownloadManager extends EventDispatcher +{ + public static DOWNLOADER_READY: string = 'AADM_DOWNLOADER_READY'; + public static LIBRARY_LOADED: string = 'AADM_LIBRARY_LOADED'; + + private static MAX_DOWNLOADS: number = 2; + + private _assets: IAssetManager; + private _structure: AvatarStructure; + + private _missingMandatoryLibs: string[]; + private _figureMap: Map; + private _pendingContainers: [ IAvatarFigureContainer, IAvatarImageListener ][]; + private _figureListeners: Map; + private _incompleteFigures: Map; + private _pendingDownloadQueue: AvatarAssetDownloadLibrary[]; + private _currentDownloads: AvatarAssetDownloadLibrary[]; + private _libraryNames: string[]; + private _isReady: boolean; + + constructor(assets: IAssetManager, structure: AvatarStructure) + { + super(); + + this._assets = assets; + this._structure = structure; + + this._missingMandatoryLibs = Nitro.instance.getConfiguration('avatar.mandatory.libraries'); + this._figureMap = new Map(); + this._pendingContainers = []; + this._figureListeners = new Map(); + this._incompleteFigures = new Map(); + this._pendingDownloadQueue = []; + this._currentDownloads = []; + this._libraryNames = []; + this._isReady = false; + + this.onLibraryLoaded = this.onLibraryLoaded.bind(this); + this.onAvatarRenderReady = this.onAvatarRenderReady.bind(this); + + this.loadFigureMap(); + + this._structure.renderManager.events.addEventListener(AvatarRenderEvent.AVATAR_RENDER_READY, this.onAvatarRenderReady); + } + + private loadFigureMap(): void + { + const request = new XMLHttpRequest(); + + try + { + request.open('GET', Nitro.instance.getConfiguration('avatar.figuremap.url')); + + request.send(); + + request.onloadend = e => + { + if(request.responseText) + { + const data = JSON.parse(request.responseText); + + this.processFigureMap(data.libraries); + + this.processMissingLibraries(); + + this._isReady = true; + + this.dispatchEvent(new NitroEvent(AvatarAssetDownloadManager.DOWNLOADER_READY)); + } + }; + + request.onerror = e => + { + throw new Error('invalid_avatar_figure_map'); + }; + } + + catch (e) + { + NitroLogger.log(e); + } + } + + private processFigureMap(data: any): void + { + if(!data) return; + + for(const library of data) + { + if(!library) continue; + + const id = (library.id as string); + const revision = (library.revision || ''); + + if(this._libraryNames.indexOf(id) >= 0) continue; + + this._libraryNames.push(id); + + const downloadLibrary = new AvatarAssetDownloadLibrary(id, revision, this._assets, Nitro.instance.getConfiguration('avatar.asset.url')); + + downloadLibrary.addEventListener(AvatarRenderLibraryEvent.DOWNLOAD_COMPLETE, this.onLibraryLoaded); + + for(const part of library.parts) + { + const id = (part.id as string); + const type = (part.type as string); + const partString = (type + ':' + id); + + let existing = this._figureMap.get(partString); + + if(!existing) existing = []; + + existing.push(downloadLibrary); + + this._figureMap.set(partString, existing); + } + } + } + + private onAvatarRenderReady(event: NitroEvent): void + { + if(!event) return; + + for(const [ container, listener ] of this._pendingContainers) + { + this.downloadAvatarFigure(container, listener); + } + + this._pendingContainers = []; + } + + private onLibraryLoaded(event: AvatarRenderLibraryEvent): void + { + if(!event || !event.library) return; + + const loadedFigures: string[] = []; + + for(const [ figure, libraries ] of this._incompleteFigures.entries()) + { + let isReady = true; + + for(const library of libraries) + { + if(!library || library.isLoaded) continue; + + isReady = false; + + break; + } + + if(isReady) + { + loadedFigures.push(figure); + + const listeners = this._figureListeners.get(figure); + + if(listeners) + { + for(const listener of listeners) + { + if(!listener || listener.disposed) continue; + + listener.resetFigure(figure); + } + } + + this._figureListeners.delete(figure); + + this.dispatchEvent(new NitroEvent(AvatarAssetDownloadManager.LIBRARY_LOADED)); + } + } + + for(const figure of loadedFigures) + { + if(!figure) continue; + + this._incompleteFigures.delete(figure); + } + + let index = 0; + + while(index < this._currentDownloads.length) + { + const download = this._currentDownloads[index]; + + if(download) + { + if(download.libraryName === event.library.libraryName) this._currentDownloads.splice(index, 1); + } + + index++; + } + } + + public processMissingLibraries(): void + { + const libraries = this._missingMandatoryLibs.slice(); + + for(const library of libraries) + { + if(!library) continue; + + const map = this._figureMap.get(library); + + if(map) for(const avatar of map) avatar && this.downloadLibrary(avatar); + } + } + + public isAvatarFigureContainerReady(container: IAvatarFigureContainer): boolean + { + if(!this._isReady || !this._structure.renderManager.isReady) + { + return false; + } + + const pendingLibraries = this.getAvatarFigurePendingLibraries(container); + + return !pendingLibraries.length; + } + + private getAvatarFigurePendingLibraries(container: IAvatarFigureContainer): AvatarAssetDownloadLibrary[] + { + const pendingLibraries: AvatarAssetDownloadLibrary[] = []; + + if(!container || !this._structure) return pendingLibraries; + + const figureData = this._structure.figureData; + + if(!figureData) return pendingLibraries; + + const setKeys = container._Str_1016(); + + for(const key of setKeys) + { + const set = figureData._Str_740(key); + + if(!set) continue; + + const figurePartSet = set._Str_1020(container.getPartSetId(key)); + + if(!figurePartSet) continue; + + for(const part of figurePartSet._Str_806) + { + if(!part) continue; + + const name = (part.type + ':' + part.id); + const existing = this._figureMap.get(name); + + if(existing === undefined) continue; + + for(const library of existing) + { + if(!library || library.isLoaded) continue; + + if(pendingLibraries.indexOf(library) >= 0) continue; + + pendingLibraries.push(library); + } + } + } + + return pendingLibraries; + } + + public downloadAvatarFigure(container: IAvatarFigureContainer, listener: IAvatarImageListener): void + { + if(!this._isReady || !this._structure.renderManager.isReady) + { + this._pendingContainers.push([ container, listener ]); + + return; + } + + const figure = container._Str_1008(); + const pendingLibraries = this.getAvatarFigurePendingLibraries(container); + + if(pendingLibraries && pendingLibraries.length) + { + if(listener && !listener.disposed) + { + let listeners = this._figureListeners.get(figure); + + if(!listeners) + { + listeners = []; + + this._figureListeners.set(figure, listeners); + } + + listeners.push(listener); + } + + this._incompleteFigures.set(figure, pendingLibraries); + + for(const library of pendingLibraries) + { + if(!library) continue; + + this.downloadLibrary(library); + } + } + else + { + if(listener && !listener.disposed) listener.resetFigure(figure); + } + } + + private downloadLibrary(library: AvatarAssetDownloadLibrary): void + { + if(!library || library.isLoaded) return; + + if((this._pendingDownloadQueue.indexOf(library) >= 0) || (this._currentDownloads.indexOf(library) >= 0)) return; + + this._pendingDownloadQueue.push(library); + + this.processDownloadQueue(); + } + + private processDownloadQueue(): void + { + while(this._pendingDownloadQueue.length) + { + const library = this._pendingDownloadQueue[0]; + + library.downloadAsset(); + + this._currentDownloads.push(this._pendingDownloadQueue.shift()); + } + } +} diff --git a/src/nitro/avatar/AvatarFigureContainer.ts b/src/nitro/avatar/AvatarFigureContainer.ts new file mode 100644 index 00000000..8b0fc32c --- /dev/null +++ b/src/nitro/avatar/AvatarFigureContainer.ts @@ -0,0 +1,116 @@ +import { IAvatarFigureContainer } from './IAvatarFigureContainer'; + +export class AvatarFigureContainer implements IAvatarFigureContainer +{ + private _parts: Map>; + + constructor(figure: string) + { + this._parts = new Map(); + + this.parseFigure(figure); + } + + public _Str_1016(): IterableIterator + { + return this.partSets().keys(); + } + + public _Str_744(k: string): boolean + { + return this.partSets().get(k) !== null; + } + + public getPartSetId(k: string): number + { + const existing = this.partSets().get(k); + + if(!existing) return 0; + + return existing.get('setid'); + } + + public _Str_815(k: string): number[] + { + const existing = this.partSets().get(k); + + if(!existing) return null; + + return existing.get('colorids'); + } + + public _Str_830(k: string, _arg_2: number, _arg_3: number[]): void + { + const set: Map = new Map(); + + set.set('type', k); + set.set('setid', _arg_2); + set.set('colorids', _arg_3); + + const existingSets = this.partSets(); + + existingSets.delete(k); + existingSets.set(k, set); + } + + public _Str_923(k: string): void + { + this.partSets().delete(k); + } + + public _Str_1008(): string + { + const parts: string[] = []; + + for(const key of this.partSets().keys()) + { + if(!key) continue; + + let setParts = []; + + setParts.push(key); + setParts.push(this.getPartSetId(key)); + + setParts = setParts.concat(this._Str_815(key)); + + parts.push(setParts.join('-')); + } + + return parts.join('.'); + } + + private partSets(): Map> + { + if(!this._parts) this._parts = new Map(); + + return this._parts; + } + + private parseFigure(figure: string): void + { + if(!figure) figure = ''; + + for(const part of figure.split('.')) + { + const pieces = part.split('-'); + + if(pieces.length >= 2) + { + const type = pieces[0]; + const setId = parseInt(pieces[1]); + const colors = []; + + let index = 2; + + while(index < pieces.length) + { + colors.push(parseInt(pieces[index])); + + index++; + } + + this._Str_830(type, setId, colors); + } + } + } +} \ No newline at end of file diff --git a/src/nitro/avatar/AvatarImage.ts b/src/nitro/avatar/AvatarImage.ts new file mode 100644 index 00000000..7f7ab6eb --- /dev/null +++ b/src/nitro/avatar/AvatarImage.ts @@ -0,0 +1,1055 @@ +import { Container, filters, Rectangle, RenderTexture, Sprite, Texture } from 'pixi.js'; +import { AdvancedMap } from '../../core/utils/AdvancedMap'; +import { IGraphicAsset } from '../../room/object/visualization/utils/IGraphicAsset'; +import { TextureUtils } from '../../room/utils/TextureUtils'; +import { Nitro } from '../Nitro'; +import { ActiveActionData } from './actions/ActiveActionData'; +import { IActionDefinition } from './actions/IActionDefinition'; +import { IActiveActionData } from './actions/IActiveActionData'; +import { AssetAliasCollection } from './alias/AssetAliasCollection'; +import { IAnimationLayerData } from './animation/IAnimationLayerData'; +import { IAvatarDataContainer } from './animation/IAvatarDataContainer'; +import { ISpriteDataContainer } from './animation/ISpriteDataContainer'; +import { AvatarFigureContainer } from './AvatarFigureContainer'; +import { AvatarStructure } from './AvatarStructure'; +import { AvatarImageCache } from './cache/AvatarImageCache'; +import { EffectAssetDownloadManager } from './EffectAssetDownloadManager'; +import { AvatarAction } from './enum/AvatarAction'; +import { AvatarDirectionAngle } from './enum/AvatarDirectionAngle'; +import { AvatarScaleType } from './enum/AvatarScaleType'; +import { AvatarSetType } from './enum/AvatarSetType'; +import { IAvatarEffectListener } from './IAvatarEffectListener'; +import { IAvatarFigureContainer } from './IAvatarFigureContainer'; +import { IAvatarImage } from './IAvatarImage'; +import { IPartColor } from './structure/figure/IPartColor'; + +export class AvatarImage implements IAvatarImage, IAvatarEffectListener +{ + private static CHANNELS_EQUAL: string = 'CHANNELS_EQUAL'; + private static CHANNELS_UNIQUE: string = 'CHANNELS_UNIQUE'; + private static CHANNELS_RED: string = 'CHANNELS_RED'; + private static CHANNELS_GREEN: string = 'CHANNELS_GREEN'; + private static CHANNELS_BLUE: string = 'CHANNELS_BLUE'; + private static CHANNELS_DESATURATED: string = 'CHANNELS_DESATURATED'; + private static DEFAULT_ACTION: string = 'Default'; + private static DEFAULT_DIRECTION: number = 2; + private static DEFAULT_AVATAR_SET: string = AvatarSetType.FULL; + + protected _structure: AvatarStructure; + protected _scale: string; + protected _mainDirection: number; + protected _headDirection: number; + protected _mainAction: IActiveActionData; + protected _disposed: boolean; + protected _canvasOffsets: number[]; + protected _assets: AssetAliasCollection; + protected _cache: AvatarImageCache; + protected _figure: AvatarFigureContainer; + protected _avatarSpriteData: IAvatarDataContainer; + protected _actions: ActiveActionData[]; + protected _image: RenderTexture; + protected _reusableTexture: RenderTexture; + + private _defaultAction: IActiveActionData; + private _frameCounter: number = 0; + private _directionOffset: number = 0; + private _changes: boolean; + private _sprites: ISpriteDataContainer[]; + private _isAnimating: boolean = false; + private _animationHasResetOnToggle: boolean = false; + private _actionsSorted: boolean = false; + private _sortedActions: IActiveActionData[]; + private _lastActionsString: string; + private _currentActionsString: string; + private _fullImageCache: AdvancedMap; + private _fullImageCacheSize: number = 5; + protected _isCachedImage: boolean = false; + private _useFullImageCache: boolean = false; + private _effectIdInUse: number = -1; + private _animationFrameCount: number; + private _cachedBodyParts: string[]; + private _cachedBodyPartsDirection: number = -1; + private _cachedBodyPartsGeometryType: string = null; + private _cachedBodyPartsAvatarSet: string = null; + private _effectManager: EffectAssetDownloadManager; + private _effectListener: IAvatarEffectListener; + + constructor(k: AvatarStructure, _arg_2: AssetAliasCollection, _arg_3: AvatarFigureContainer, _arg_4: string, _arg_5: EffectAssetDownloadManager, _arg_6: IAvatarEffectListener = null) + { + this._canvasOffsets = []; + this._actions = []; + this._cachedBodyParts = []; + this._changes = true; + this._disposed = false; + this._effectManager = _arg_5; + this._structure = k; + this._assets = _arg_2; + this._scale = _arg_4; + this._effectListener = _arg_6; + if(this._scale == null) + { + this._scale = AvatarScaleType.LARGE; + } + if(_arg_3 == null) + { + _arg_3 = new AvatarFigureContainer('hr-893-45.hd-180-2.ch-210-66.lg-270-82.sh-300-91.wa-2007-.ri-1-'); + } + this._figure = _arg_3; + this._cache = new AvatarImageCache(this._structure, this, this._assets, this._scale); + this.setDirection(AvatarImage.DEFAULT_AVATAR_SET, AvatarImage.DEFAULT_DIRECTION); + this._actions = []; + this._defaultAction = new ActiveActionData(AvatarAction.POSTURE_STAND); + this._defaultAction._Str_742 = this._structure._Str_1675(AvatarImage.DEFAULT_ACTION); + this.resetActions(); + this._fullImageCache = new AdvancedMap(); + this._animationFrameCount = 0; + } + + public getServerRenderData(): any[] + { + this.getAvatarPartsForCamera(AvatarSetType.FULL); + + return this._cache._Str_1009(); + } + + public dispose(): void + { + if(this._disposed) return; + + this._structure = null; + this._assets = null; + this._mainAction = null; + this._figure = null; + this._avatarSpriteData = null; + this._actions = null; + + if(this._image) + { + this._image.destroy(); + + this._image = null; + } + + if(this._cache) + { + this._cache.dispose(); + this._cache = null; + } + + if(this._fullImageCache) + { + for(const k of this._fullImageCache.getValues()) (k && k.destroy()); + + this._fullImageCache = null; + } + + this._image = null; + this._canvasOffsets = null; + this._disposed = true; + } + + public get disposed(): boolean + { + return this._disposed; + } + + public getFigure(): IAvatarFigureContainer + { + return this._figure; + } + + public getScale(): string + { + return this._scale; + } + + public getPartColor(k: string): IPartColor + { + return this._structure._Str_867(this._figure, k); + } + + public setDirection(k: string, _arg_2: number): void + { + _arg_2 = (_arg_2 + this._directionOffset); + + if(_arg_2 < AvatarDirectionAngle.MIN_DIRECTION) + { + _arg_2 = (AvatarDirectionAngle.MAX_DIRECTION + (_arg_2 + 1)); + } + + if(_arg_2 > AvatarDirectionAngle.MAX_DIRECTION) + { + _arg_2 = (_arg_2 - (AvatarDirectionAngle.MAX_DIRECTION + 1)); + } + + if(this._structure._Str_1939(k)) + { + this._mainDirection = _arg_2; + } + + if((k === AvatarSetType.HEAD) || (k === AvatarSetType.FULL)) + { + if((k === AvatarSetType.HEAD) && (this.isHeadTurnPreventedByAction())) + { + _arg_2 = this._mainDirection; + } + + this._headDirection = _arg_2; + } + + this._cache.setDirection(k, _arg_2); + this._changes = true; + } + + public setDirectionAngle(k: string, _arg_2: number): void + { + this.setDirection(k, Math.floor(_arg_2 / 45)); + } + + public getSprites(): ISpriteDataContainer[] + { + return this._sprites; + } + + public getCanvasOffsets(): number[] + { + return this._canvasOffsets; + } + + public getLayerData(k: ISpriteDataContainer): IAnimationLayerData + { + return this._structure._Str_1881(k.animation.id, this._frameCounter, k.id); + } + + public updateAnimationByFrames(k: number = 1): void + { + this._frameCounter += k; + this._changes = true; + } + + public resetAnimationFrameCounter(): void + { + this._frameCounter = 0; + this._changes = true; + } + + private getFullImageCacheKey(): string + { + if(!this._useFullImageCache) return null; + + if(((this._sortedActions.length == 1) && (this._mainDirection == this._headDirection))) + { + return (this._mainDirection + this._currentActionsString) + (this._frameCounter % 4); + } + + if(this._sortedActions.length == 2) + { + for(const k of this._sortedActions) + { + if(((k._Str_695 == 'fx') && ((((k._Str_727 == '33') || (k._Str_727 == '34')) || (k._Str_727 == '35')) || (k._Str_727 == '36')))) + { + return (this._mainDirection + this._currentActionsString) + 0; + } + + if(((k._Str_695 == 'fx') && ((k._Str_727 == '38') || (k._Str_727 == '39')))) + { + return (((this._mainDirection + '_') + this._headDirection) + this._currentActionsString) + (this._frameCounter % 11); + } + + if((k._Str_695 === 'dance') && ((k._Str_727 === '1') || (k._Str_727 === '2') || (k._Str_727 === '3') || (k._Str_727 === '4'))) + { + let frame = (this._frameCounter % 8); + + if((k._Str_727 === '3')) frame = (this._frameCounter % 10); + + if((k._Str_727 === '4')) frame = (this._frameCounter % 16); + + return (((this._mainDirection + k._Str_695) + k._Str_727) + frame); + } + } + } + + return null; + } + + private getBodyParts(k: string, _arg_2: string, _arg_3: number): string[] + { + if((((!(_arg_3 == this._cachedBodyPartsDirection)) || (!(_arg_2 == this._cachedBodyPartsGeometryType))) || (!(k == this._cachedBodyPartsAvatarSet)))) + { + this._cachedBodyPartsDirection = _arg_3; + this._cachedBodyPartsGeometryType = _arg_2; + this._cachedBodyPartsAvatarSet = k; + this._cachedBodyParts = this._structure._Str_755(k, _arg_2, _arg_3); + } + return this._cachedBodyParts; + } + + public getAvatarPartsForCamera(k: string): void + { + let _local_4: string; + if(this._mainAction == null) + { + return; + } + const _local_2 = this._structure._Str_1664(this._scale, this._mainAction._Str_742._Str_868); + if(_local_2 == null) + { + return; + } + const _local_3 = this.getBodyParts(k, this._mainAction._Str_742._Str_868, this._mainDirection); + let _local_6 = (_local_3.length - 1); + while(_local_6 >= 0) + { + _local_4 = _local_3[_local_6]; + const _local_5 = this._cache._Str_1629(_local_4, this._frameCounter, true); + _local_6--; + } + } + + public getImage(setType: string, hightlight: boolean, scale: number = 1, cache: boolean = true): RenderTexture + { + if(!this._changes) return this._image; + + if(!this._mainAction) return null; + + if(!this._actionsSorted) this.endActionAppends(); + + const avatarCanvas = this._structure._Str_1664(this._scale, this._mainAction._Str_742._Str_868); + + if(!avatarCanvas) return null; + + if(this._image && ((this._image.width !== avatarCanvas.width) || (this._image.height !== avatarCanvas.height))) + { + if(this._reusableTexture) + { + this._reusableTexture.destroy(true); + + this._reusableTexture = null; + } + + this._image = null; + this._isCachedImage = false; + } + + const _local_6 = this.getBodyParts(setType, this._mainAction._Str_742._Str_868, this._mainDirection); + + this._image = null; + + const container = new Container(); + + let isCachable = true; + let partCount = (_local_6.length - 1); + + while(partCount >= 0) + { + const set = _local_6[partCount]; + const part = this._cache._Str_1629(set, this._frameCounter); + + if(part) + { + const partCacheContainer = part.image; + + if(!partCacheContainer) + { + container.destroy({ + children: true + }); + + return null; + } + + isCachable = ((isCachable) && (part._Str_1807)); + + const point = part._Str_1076.clone(); + + if(point) + { + point.x += avatarCanvas.offset.x; + point.y += avatarCanvas.offset.y; + + point.x += avatarCanvas._Str_1076.x; + point.y += avatarCanvas._Str_1076.y; + + const partContainer = new Container(); + + partContainer.addChild(partCacheContainer); + + if(partContainer) + { + partContainer.position.set(point.x, point.y); + + container.addChild(partContainer); + } + } + } + + partCount--; + } + + if(this._avatarSpriteData && this._avatarSpriteData._Str_832) this.convertToGrayscale(container); + + if(!cache) + { + return TextureUtils.generateTexture(container, new Rectangle(0, 0, avatarCanvas.width, avatarCanvas.height)); + } + + if(this._reusableTexture) + { + Nitro.instance.renderer.render(container, this._reusableTexture, true); + } + else + { + this._reusableTexture = TextureUtils.generateTexture(container, new Rectangle(0, 0, avatarCanvas.width, avatarCanvas.height)); + } + + if(!this._reusableTexture) return null; + + if(this._avatarSpriteData && this._avatarSpriteData._Str_832) + { + //this._reusableTexture = this.applyPalette(this._reusableTexture, this._avatarSpriteData.reds); + } + + this._image = this._reusableTexture; + this._changes = false; + + return this._image; + } + + // public applyPalette(texture: RenderTexture, reds: number[] = [], greens: number[] = [], blues: number[] = []): RenderTexture + // { + // const textureCanvas = Nitro.instance.renderer.extract.canvas(texture); + // const textureCtx = textureCanvas.getContext('2d'); + // const textureImageData = textureCtx.getImageData(0, 0, textureCanvas.width, textureCanvas.height); + // const data = textureImageData.data; + + // for(const i = 0; i < data.length; i += 4) + // { + // let paletteColor = this._palette[data[ i + 1 ]]; + + // if(paletteColor === undefined) paletteColor = [ 0, 0, 0 ]; + + // data[ i ] = paletteColor[0]; + // data[ i + 1 ] = paletteColor[1]; + // data[ i + 2 ] = paletteColor[2]; + // } + + // textureCtx.putImageData(textureImageData, 0, 0); + + // return Texture.from(textureCanvas); + // } + + public getImageAsSprite(setType: string, scale: number = 1): Sprite + { + if(!this._mainAction) return null; + + if(!this._actionsSorted) this.endActionAppends(); + + const avatarCanvas = this._structure._Str_1664(this._scale, this._mainAction._Str_742._Str_868); + + if(!avatarCanvas) return null; + + const setTypes = this.getBodyParts(setType, this._mainAction._Str_742._Str_868, this._mainDirection); + const container = new Sprite(); + const sprite = new Sprite(Texture.EMPTY); + + sprite.width = avatarCanvas.width; + sprite.height = avatarCanvas.height; + + container.addChild(sprite); + + let partCount = (setTypes.length - 1); + + while(partCount >= 0) + { + const set = setTypes[partCount]; + const part = this._cache._Str_1629(set, this._frameCounter); + + if(part) + { + const partCacheContainer = part.image; + + if(!partCacheContainer) + { + container.destroy({ + children: true + }); + + return null; + } + + const point = part._Str_1076.clone(); + + if(point) + { + point.x += avatarCanvas.offset.x; + point.y += avatarCanvas.offset.y; + + point.x += avatarCanvas._Str_1076.x; + point.y += avatarCanvas._Str_1076.y; + + const partContainer = new Container(); + + partContainer.addChild(partCacheContainer); + + partContainer.position.set(point.x, point.y); + + container.addChild(partContainer); + } + } + + partCount--; + } + + return container; + } + + public getCroppedImage(setType: string, scale: number = 1): HTMLImageElement + { + if(!this._mainAction) return null; + + if(!this._actionsSorted) this.endActionAppends(); + + const avatarCanvas = this._structure._Str_1664(this._scale, this._mainAction._Str_742._Str_868); + + if(!avatarCanvas) return null; + + const setTypes = this.getBodyParts(setType, this._mainAction._Str_742._Str_868, this._mainDirection); + const container = new Container(); + const sprite = new Sprite(Texture.EMPTY); + + sprite.width = avatarCanvas.width; + sprite.height = avatarCanvas.height; + + container.addChild(sprite); + + let partCount = (setTypes.length - 1); + + while(partCount >= 0) + { + const set = setTypes[partCount]; + const part = this._cache._Str_1629(set, this._frameCounter); + + if(part) + { + const partCacheContainer = part.image; + + if(!partCacheContainer) + { + container.destroy({ + children: true + }); + + return null; + } + + const point = part._Str_1076.clone(); + + if(point) + { + point.x += avatarCanvas.offset.x; + point.y += avatarCanvas.offset.y; + + point.x += avatarCanvas._Str_1076.x; + point.y += avatarCanvas._Str_1076.y; + + const partContainer = new Container(); + + partContainer.addChild(partCacheContainer); + + if(partContainer) + { + partContainer.position.set(point.x, point.y); + + container.addChild(partContainer); + } + } + } + + partCount--; + } + + const image = Nitro.instance.renderer.extract.image(container); + + if(!image) return null; + + return image; + } + + protected getFullImage(k: string): RenderTexture + { + const existing = this._fullImageCache.getValue(k); + + if(existing) + { + if(!existing.valid) + { + this._fullImageCache.remove(k); + + existing.destroy(true); + } + + return existing; + } + + return null; + } + + protected cacheFullImage(k: string, _arg_2: RenderTexture): void + { + const existing = this._fullImageCache.getValue(k); + + if(existing) + { + this._fullImageCache.remove(k); + + existing.destroy(true); + } + + if(this._fullImageCache.length === this._fullImageCacheSize) + { + const oldestKey = this._fullImageCache.getKey(0); + + if(oldestKey) + { + const removed = this._fullImageCache.remove(oldestKey); + + removed.destroy(true); + } + } + + this._fullImageCache.add(k, _arg_2); + } + + public getAsset(k: string): IGraphicAsset + { + return this._assets.getAsset(k); + } + + public getDirection(): number + { + return this._mainDirection; + } + + public initActionAppends(): void + { + this._actions = []; + this._actionsSorted = false; + this._currentActionsString = ''; + this._useFullImageCache = false; + } + + public endActionAppends(): void + { + let k:ActiveActionData; + + if(!this.sortActions()) return; + + for(const k of this._sortedActions) + { + if(k._Str_695 === AvatarAction.EFFECT) + { + if(!this._effectManager.isAvatarEffectReady(parseInt(k._Str_727))) this._effectManager.downloadAvatarEffect(parseInt(k._Str_727), this); + } + } + + this.resetActions(); + this.setActionsToParts(); + } + + public appendAction(k: string, ..._args: any[]): boolean + { + let _local_3 = ''; + + this._actionsSorted = false; + + if(_args && (_args.length > 0)) _local_3 = _args[0]; + + if((_local_3 !== undefined) && (_local_3 !== null)) _local_3 = _local_3.toString(); + + switch(k) + { + case AvatarAction.POSTURE: + switch(_local_3) + { + case AvatarAction.POSTURE_LAY: + if(this._mainDirection == 0) + { + this.setDirection(AvatarSetType.FULL, 4); + } + else + { + this.setDirection(AvatarSetType.FULL, 2); + } + // eslint-disable-next-line no-fallthrough + case AvatarAction.POSTURE_WALK: + case AvatarAction.POSTURE_STAND: + this._useFullImageCache = true; + this._useFullImageCache = true; + // eslint-disable-next-line no-fallthrough + case AvatarAction.POSTURE_SWIM: + case AvatarAction.POSTURE_FLOAT: + case AvatarAction.POSTURE_SIT: + case AvatarAction.SNOWWAR_RUN: + case AvatarAction.SNOWWAR_DIE_FRONT: + case AvatarAction.SNOWWAR_DIE_BACK: + case AvatarAction.SNOWWAR_PICK: + case AvatarAction.SNOWWAR_THROW: + this.addActionData(_local_3); + break; + } + break; + case AvatarAction.GESTURE: + switch(_local_3) + { + case AvatarAction.GESTURE_AGGRAVATED: + case AvatarAction.GESTURE_SAD: + case AvatarAction.GESTURE_SMILE: + case AvatarAction.GESTURE_SURPRISED: + this.addActionData(_local_3); + break; + } + break; + case AvatarAction.EFFECT: + if((((((_local_3 === '33') || (_local_3 === '34')) || (_local_3 === '35')) || (_local_3 === '36')) || (_local_3 === '38')) || (_local_3 === '39')) + { + this._useFullImageCache = true; + } + // eslint-disable-next-line no-fallthrough + case AvatarAction.DANCE: + case AvatarAction.TALK: + case AvatarAction.EXPRESSION_WAVE: + case AvatarAction.SLEEP: + case AvatarAction.SIGN: + case AvatarAction.EXPRESSION_RESPECT: + case AvatarAction.EXPRESSION_BLOW_A_KISS: + case AvatarAction.EXPRESSION_LAUGH: + case AvatarAction.EXPRESSION_CRY: + case AvatarAction.EXPRESSION_IDLE: + case AvatarAction.EXPRESSION_SNOWBOARD_OLLIE: + case AvatarAction.EXPRESSION_SNOWBORD_360: + case AvatarAction.EXPRESSION_RIDE_JUMP: + this.addActionData(k, _local_3); + break; + case AvatarAction.CARRY_OBJECT: + case AvatarAction.USE_OBJECT: { + const _local_4 = this._structure._Str_2018(k); + if(_local_4) _local_3 = _local_4._Str_1350(_local_3); + this.addActionData(k, _local_3); + break; + } + } + + return true; + } + + protected addActionData(k: string, _arg_2: string=''): void + { + let _local_3:ActiveActionData; + if(!this._actions) this._actions = []; + + let _local_4 = 0; + while(_local_4 < this._actions.length) + { + _local_3 = this._actions[_local_4]; + if(((_local_3._Str_695 == k) && (_local_3._Str_727 == _arg_2))) + { + return; + } + _local_4++; + } + this._actions.push(new ActiveActionData(k, _arg_2, this._frameCounter)); + } + + public isAnimating(): boolean + { + return (this._isAnimating) || (this._animationFrameCount > 1); + } + + private resetActions(): boolean + { + this._animationHasResetOnToggle = false; + this._isAnimating = false; + this._sprites = []; + this._avatarSpriteData = null; + this._directionOffset = 0; + this._structure._Str_2101(this); + this._mainAction = this._defaultAction; + this._mainAction._Str_742 = this._defaultAction._Str_742; + this.resetBodyPartCache(this._defaultAction); + return true; + } + + private isHeadTurnPreventedByAction(): boolean + { + let _local_2: IActionDefinition; + let _local_3: ActiveActionData; + let k: boolean; + if(this._sortedActions == null) + { + return false; + } + for(const _local_3 of this._sortedActions) + { + _local_2 = this._structure._Str_2018(_local_3._Str_695); + if(((!(_local_2 == null)) && (_local_2._Str_715(_local_3._Str_727)))) + { + k = true; + } + } + return k; + } + + private sortActions(): boolean + { + let _local_2: boolean; + let _local_3: boolean; + let _local_4:ActiveActionData; + let _local_5: number; + let k: boolean; + + this._currentActionsString = ''; + this._sortedActions = this._structure._Str_711(this._actions); + this._animationFrameCount = this._structure._Str_1936(this._sortedActions); + + if(!this._sortedActions) + { + this._canvasOffsets = [ 0, 0, 0 ]; + + if(this._lastActionsString !== '') + { + k = true; + + this._lastActionsString = ''; + } + } + else + { + this._canvasOffsets = this._structure._Str_781(this._sortedActions, this._scale, this._mainDirection); + + for(const _local_4 of this._sortedActions) + { + this._currentActionsString = (this._currentActionsString + (_local_4._Str_695 + _local_4._Str_727)); + + if(_local_4._Str_695 === AvatarAction.EFFECT) + { + const _local_5 = parseInt(_local_4._Str_727); + + if(this._effectIdInUse !== _local_5) _local_2 = true; + + this._effectIdInUse = _local_5; + + _local_3 = true; + } + } + + if(!_local_3) + { + if(this._effectIdInUse > -1) _local_2 = true; + + this._effectIdInUse = -1; + } + + if(_local_2) this._cache._Str_1086(0); + + if(this._lastActionsString != this._currentActionsString) + { + k = true; + + this._lastActionsString = this._currentActionsString; + } + } + + this._actionsSorted = true; + + return k; + } + + private setActionsToParts(): void + { + if(!this._sortedActions == null) return; + + const _local_3: number = Nitro.instance.time; + const _local_4: string[] = []; + + for(const k of this._sortedActions) _local_4.push(k._Str_695); + + for(const k of this._sortedActions) + { + if((k && k._Str_742) && k._Str_742._Str_861) + { + const _local_2 = this._structure._Str_720(((k._Str_742.state + '.') + k._Str_727)); + + if(_local_2 && _local_2._Str_1892()) + { + const _local_5 = _local_2._Str_1571(); + + if(_local_5) + { + for(const _local_6 of _local_5) + { + if(_local_4.indexOf(_local_6) >= 0) k._Str_707 = _local_2._Str_707(_local_6); + } + } + } + + if(_local_2 && _local_2.resetOnToggle) + { + this._animationHasResetOnToggle = true; + } + } + } + + for(const k of this._sortedActions) + { + if(!((!(k)) || (!(k._Str_742)))) + { + if(k._Str_742._Str_861 && (k._Str_727 === '')) k._Str_727 = '1'; + + this.setActionToParts(k, _local_3); + + if(k._Str_742._Str_861) + { + this._isAnimating = k._Str_742._Str_801(k._Str_727); + + const _local_2 = this._structure._Str_720(((k._Str_742.state + '.') + k._Str_727)); + + if(_local_2) + { + this._sprites = this._sprites.concat(_local_2._Str_786); + + if(_local_2._Str_776()) this._directionOffset = _local_2._Str_1493.offset; + + if(_local_2._Str_872()) this._avatarSpriteData = _local_2._Str_1475; + } + } + } + } + } + + private setActionToParts(k: IActiveActionData, _arg_2: number): void + { + if(((k == null) || (k._Str_742 == null))) + { + return; + } + if(k._Str_742._Str_778 == '') + { + return; + } + if(k._Str_742._Str_779) + { + this._mainAction = k; + this._cache._Str_2014(k._Str_742._Str_868); + } + this._cache._Str_1565(k, _arg_2); + this._changes = true; + } + + private resetBodyPartCache(k: IActiveActionData): void + { + if(!k) return; + + if(k._Str_742._Str_778 === '') return; + + if(k._Str_742._Str_779) + { + this._mainAction = k; + this._cache._Str_2014(k._Str_742._Str_868); + } + + this._cache._Str_741(k); + this._changes = true; + } + + public get avatarSpriteData(): IAvatarDataContainer + { + return this._avatarSpriteData; + } + + private convertToGrayscale(container: Container, channel: string = 'CHANNELS_EQUAL'): Container + { + let _local_3 = 0.33; + let _local_4 = 0.33; + let _local_5 = 0.33; + const _local_6 = 1; + + switch(channel) + { + case AvatarImage.CHANNELS_UNIQUE: + _local_3 = 0.3; + _local_4 = 0.59; + _local_5 = 0.11; + break; + case AvatarImage.CHANNELS_RED: + _local_3 = 1; + _local_4 = 0; + _local_5 = 0; + break; + case AvatarImage.CHANNELS_GREEN: + _local_3 = 0; + _local_4 = 1; + _local_5 = 0; + break; + case AvatarImage.CHANNELS_BLUE: + _local_3 = 0; + _local_4 = 0; + _local_5 = 1; + break; + case AvatarImage.CHANNELS_DESATURATED: + _local_3 = 0.3086; + _local_4 = 0.6094; + _local_5 = 0.082; + break; + } + + const colorFilter = new filters.ColorMatrixFilter(); + + colorFilter.matrix = [_local_3, _local_4, _local_5, 0, 0, _local_3, _local_4, _local_5, 0, 0, _local_3, _local_4, _local_5, 0, 0, 0, 0, 0, 1, 0]; + + container.filters = [ colorFilter ]; + + return container; + } + + private errorThis(k: string): void + { + } + + private logThis(k: string): void + { + } + + public isPlaceholder(): boolean + { + return false; + } + + public forceActionUpdate(): void + { + this._lastActionsString = ''; + } + + public get animationHasResetOnToggle(): boolean + { + return this._animationHasResetOnToggle; + } + + public get mainAction(): string + { + return this._mainAction._Str_695; + } + + public resetEffect(effect: number): void + { + if(effect === this._effectIdInUse) + { + this.resetActions(); + this.setActionsToParts(); + + this._animationHasResetOnToggle = true; + this._changes = true; + + if(this._effectListener) this._effectListener.resetEffect(effect); + } + } +} diff --git a/src/nitro/avatar/AvatarImageBodyPartContainer.ts b/src/nitro/avatar/AvatarImageBodyPartContainer.ts new file mode 100644 index 00000000..941ea6dc --- /dev/null +++ b/src/nitro/avatar/AvatarImageBodyPartContainer.ts @@ -0,0 +1,88 @@ +import { Container, Point } from 'pixi.js'; + +export class AvatarImageBodyPartContainer +{ + private _image: Container; + private _regPoint: Point; + private _offset: Point; + private _isCacheable: boolean; + + constructor(k: Container, _arg_2: Point, _arg_3: boolean) + { + this._image = k; + this._regPoint = _arg_2; + this._offset = new Point(0, 0); + this._regPoint = _arg_2; + this._isCacheable = _arg_3; + + this._Str_1225(); + } + + public dispose(): void + { + if(this._image) + { + this._image.destroy({ + children: true + }); + } + + this._image = null; + this._regPoint = null; + this._offset = null; + } + + private _Str_1225(): void + { + // this._regPoint.x = this._regPoint.x; + // this._regPoint.y = this._regPoint.y; + // this._offset.x = this._offset.x; + // this._offset.y = this._offset.y; + } + + public _Str_1387(k: Point): void + { + this._regPoint = k; + + this._Str_1225(); + } + + public get image(): Container + { + return this._image; + } + + public set image(k: Container) + { + if(this._image && (this._image !== k)) + { + this._image.destroy({ + children: true + }); + } + + this._image = k; + } + + public get _Str_1076(): Point + { + const clone = this._regPoint.clone(); + + clone.x += this._offset.x; + clone.y += this._offset.y; + + return clone; + } + + public set offset(k: Point) + { + this._offset = k; + + this._Str_1225(); + } + + public get _Str_1807(): boolean + { + return this._isCacheable; + } +} \ No newline at end of file diff --git a/src/nitro/avatar/AvatarImagePartContainer.ts b/src/nitro/avatar/AvatarImagePartContainer.ts new file mode 100644 index 00000000..02e10d9a --- /dev/null +++ b/src/nitro/avatar/AvatarImagePartContainer.ts @@ -0,0 +1,137 @@ +import { AdjustmentFilter } from '@pixi/filter-adjustment'; +import { IActionDefinition } from './actions/IActionDefinition'; +import { AnimationFrame } from './structure/animation/AnimationFrame'; +import { IPartColor } from './structure/figure/IPartColor'; + +export class AvatarImagePartContainer +{ + private _bodyPartId: string; + private _partType: string; + private _flippedPartType: string; + private _partId: string; + private _color: IPartColor; + private _frames: AnimationFrame[]; + private _action: IActionDefinition; + private _isColorable: boolean; + private _isBlendable: boolean; + private _blendTransform: AdjustmentFilter; + private _paletteMapId: number; + + constructor(k: string, _arg_2: string, _arg_3: string, _arg_4: IPartColor, _arg_5: AnimationFrame[], _arg_6: IActionDefinition, _arg_7: boolean, _arg_8: number, _arg_9: string = '', _arg_10: boolean = false, _arg_11: number = 1) + { + this._bodyPartId = k; + this._partType = _arg_2; + this._partId = _arg_3; + this._color = _arg_4; + this._frames = _arg_5; + this._action = _arg_6; + this._isColorable = _arg_7; + this._paletteMapId = _arg_8; + this._flippedPartType = _arg_9; + this._isBlendable = _arg_10; + this._blendTransform = null; + + if(this._partType === 'ey') this._isColorable = false; + } + + public _Str_1674(k: number): number + { + if(!this._frames || !this._frames.length) return 0; + + const frameNumber = (k % this._frames.length); + + if(this._frames[frameNumber] instanceof AnimationFrame) + { + return this._frames[frameNumber].number; + } + + return frameNumber; + } + + public _Str_2258(k: number): AnimationFrame + { + const frameNumber = (k % this._frames.length); + + if(this._frames && (this._frames.length > frameNumber)) + { + if(this._frames[frameNumber] instanceof AnimationFrame) + { + return this._frames[frameNumber]; + } + } + + return null; + } + + public _Str_1206(k: number): string + { + const frameNumber = (k % this._frames.length); + + if(this._frames && (this._frames.length > frameNumber)) + { + if(this._frames[frameNumber] instanceof AnimationFrame) + { + const frame = this._frames[frameNumber]; + + return (this._Str_1502 + ':' + frame._Str_778 + ':' + frame.number); + } + } + + return (this._Str_1502 + ':' + frameNumber); + } + + public get _Str_1360(): string + { + return this._bodyPartId; + } + + public get _Str_1669(): string + { + return this._partType; + } + + public get _Str_1502(): string + { + return this._partId; + } + + public get color(): IPartColor + { + return this._color; + } + + public get action(): IActionDefinition + { + return this._action; + } + + public get isColorable(): boolean + { + return this._isColorable; + } + + public set isColorable(k: boolean) + { + this._isColorable = k; + } + + public get _Str_1406(): number + { + return this._paletteMapId; + } + + public get _Str_1666(): string + { + return this._flippedPartType; + } + + public get _Str_1184(): boolean + { + return this._isBlendable; + } + + public toString(): string + { + return [ this._bodyPartId, this._partType, this._partId ].join(':'); + } +} \ No newline at end of file diff --git a/src/nitro/avatar/AvatarRenderManager.ts b/src/nitro/avatar/AvatarRenderManager.ts new file mode 100644 index 00000000..ea201067 --- /dev/null +++ b/src/nitro/avatar/AvatarRenderManager.ts @@ -0,0 +1,477 @@ +import { Parser } from 'xml2js'; +import { IAssetManager } from '../../core/asset/IAssetManager'; +import { NitroManager } from '../../core/common/NitroManager'; +import { NitroEvent } from '../../core/events/NitroEvent'; +import { IGraphicAsset } from '../../room/object/visualization/utils/IGraphicAsset'; +import { Nitro } from '../Nitro'; +import { FigureDataContainer } from '../utils/FigureDataContainer'; +import { AssetAliasCollection } from './alias/AssetAliasCollection'; +import { AvatarAssetDownloadManager } from './AvatarAssetDownloadManager'; +import { AvatarFigureContainer } from './AvatarFigureContainer'; +import { AvatarImage } from './AvatarImage'; +import { AvatarStructure } from './AvatarStructure'; +import * as HabboAvatarAnimations from './data/HabboAvatarAnimations.json'; +import * as HabboAvatarGeometry from './data/HabboAvatarGeometry.json'; +import * as HabboAvatarPartSets from './data/HabboAvatarPartSets.json'; +import { EffectAssetDownloadManager } from './EffectAssetDownloadManager'; +import { AvatarSetType } from './enum/AvatarSetType'; +import { AvatarRenderEvent } from './events/AvatarRenderEvent'; +import { IAvatarEffectListener } from './IAvatarEffectListener'; +import { IAvatarFigureContainer } from './IAvatarFigureContainer'; +import { IAvatarImage } from './IAvatarImage'; +import { IAvatarImageListener } from './IAvatarImageListener'; +import { IAvatarRenderManager } from './IAvatarRenderManager'; +import { PlaceHolderAvatarImage } from './PlaceHolderAvatarImage'; +import { AvatarStructureDownload } from './structure/AvatarStructureDownload'; +import { IFigurePartSet } from './structure/figure/IFigurePartSet'; +import { IFigureSetData } from './structure/IFigureSetData'; +import { IStructureData } from './structure/IStructureData'; + +export class AvatarRenderManager extends NitroManager implements IAvatarRenderManager +{ + private static DEFAULT_FIGURE: string = 'hd-99999-99999'; + + private _aliasCollection: AssetAliasCollection; + + private _structure: AvatarStructure; + private _avatarAssetDownloadManager: AvatarAssetDownloadManager; + private _effectAssetDownloadManager: EffectAssetDownloadManager; + + private _placeHolderFigure: AvatarFigureContainer; + + private _figureMapReady: boolean; + private _effectMapReady: boolean; + private _actionsReady: boolean; + private _structureReady: boolean; + private _geometryReady: boolean; + private _partSetsReady: boolean; + private _animationsReady: boolean; + private _isReady: boolean; + + constructor() + { + super(); + + this._structure = null; + this._avatarAssetDownloadManager = null; + + this._placeHolderFigure = null; + + this._figureMapReady = false; + this._effectMapReady = false; + this._actionsReady = false; + this._geometryReady = false; + this._partSetsReady = false; + this._animationsReady = false; + this._isReady = false; + + this.onAvatarAssetDownloaderReady = this.onAvatarAssetDownloaderReady.bind(this); + this.onAvatarAssetDownloaded = this.onAvatarAssetDownloaded.bind(this); + this.onEffectAssetDownloaderReady = this.onEffectAssetDownloaderReady.bind(this); + this.onEffectAssetDownloaded = this.onEffectAssetDownloaded.bind(this); + this.onAvatarStructureDownloadDone = this.onAvatarStructureDownloadDone.bind(this); + } + + public onInit(): void + { + this._structure = new AvatarStructure(this); + + this.loadGeometry(); + this.loadPartSets(); + this.loadActions(); + this.loadAnimations(); + this.loadFigureData(); + + this._aliasCollection = new AssetAliasCollection(this, Nitro.instance.core.asset); + + this._aliasCollection.init(); + + if(!this._avatarAssetDownloadManager) + { + this._avatarAssetDownloadManager = new AvatarAssetDownloadManager(Nitro.instance.core.asset, this._structure); + + this._avatarAssetDownloadManager.addEventListener(AvatarAssetDownloadManager.DOWNLOADER_READY, this.onAvatarAssetDownloaderReady); + this._avatarAssetDownloadManager.addEventListener(AvatarAssetDownloadManager.LIBRARY_LOADED, this.onAvatarAssetDownloaded); + } + + if(!this._effectAssetDownloadManager) + { + this._effectAssetDownloadManager = new EffectAssetDownloadManager(Nitro.instance.core.asset, this._structure); + + this._effectAssetDownloadManager.addEventListener(EffectAssetDownloadManager.DOWNLOADER_READY, this.onEffectAssetDownloaderReady); + this._effectAssetDownloadManager.addEventListener(EffectAssetDownloadManager.LIBRARY_LOADED, this.onEffectAssetDownloaded); + } + + this.checkReady(); + } + + public onDispose(): void + { + if(this._avatarAssetDownloadManager) + { + this._avatarAssetDownloadManager.removeEventListener(AvatarAssetDownloadManager.DOWNLOADER_READY, this.onAvatarAssetDownloaderReady); + + this._avatarAssetDownloadManager.removeEventListener(AvatarAssetDownloadManager.LIBRARY_LOADED, this.onAvatarAssetDownloaded); + } + + if(this._effectAssetDownloadManager) + { + this._effectAssetDownloadManager.removeEventListener(EffectAssetDownloadManager.DOWNLOADER_READY, this.onEffectAssetDownloaderReady); + + this._effectAssetDownloadManager.removeEventListener(EffectAssetDownloadManager.LIBRARY_LOADED, this.onEffectAssetDownloaded); + } + } + + private loadGeometry(): void + { + if(!this._structure) return; + + this._structure._Str_1825(HabboAvatarGeometry.geometry); + + this._geometryReady = true; + + this.checkReady(); + } + + private loadPartSets(): void + { + if(!this._structure) return; + + this._structure._Str_1296(HabboAvatarPartSets.partSets); + + this._partSetsReady = true; + + this.checkReady(); + } + + private loadActions(): void + { + const defaultActions = Nitro.instance.getConfiguration('avatar.default.actions'); + + if(defaultActions) this._structure._Str_1060(Nitro.instance.core.asset, defaultActions); + + const request = new XMLHttpRequest(); + + try + { + request.open('GET', Nitro.instance.getConfiguration('avatar.actions.url')); + + request.send(); + + request.onloadend = e => + { + if(!this._structure) return; + + this._structure._Str_1620(JSON.parse(request.responseText)); + + this._actionsReady = true; + + this.checkReady(); + }; + + request.onerror = e => + { + throw new Error('invalid_avatar_actions'); + }; + } + + catch (e) + { + this.logger.error(e); + } + } + + private loadAnimations(): void + { + if(!this._structure) return; + + this._structure._Str_2229(HabboAvatarAnimations.animations); + + this._animationsReady = true; + + this.checkReady(); + } + + private loadFigureData(): void + { + const defaultFigureData = Nitro.instance.getConfiguration('avatar.default.figuredata'); + + if(defaultFigureData) + { + const parser = new Parser(); + + parser.parseString(defaultFigureData, (err: Error, results: any) => + { + if(err || !results || !results.figuredata) throw new Error('invalid_default_figure_data'); + + if(this._structure) this._structure._Str_1569(results.figuredata); + }); + } + + const structureDownloader = new AvatarStructureDownload(Nitro.instance.getConfiguration('avatar.figuredata.url'), (this._structure.figureData as IFigureSetData)); + + structureDownloader.addEventListener(AvatarStructureDownload.AVATAR_STRUCTURE_DONE, this.onAvatarStructureDownloadDone); + } + + private onAvatarStructureDownloadDone(event: NitroEvent): void + { + this._structureReady = true; + + this._structure.init(); + + this.checkReady(); + } + + private onAvatarAssetDownloaderReady(event: NitroEvent): void + { + if(!event) return; + + this._figureMapReady = true; + + this.checkReady(); + } + + private onAvatarAssetDownloaded(event: NitroEvent): void + { + if(!event) return; + + this._aliasCollection.reset(); + } + + private onEffectAssetDownloaderReady(event: NitroEvent): void + { + if(!event) return; + + this._effectMapReady = true; + + this.checkReady(); + } + + private onEffectAssetDownloaded(event: NitroEvent): void + { + if(!event) return; + + this._aliasCollection.reset(); + } + + private checkReady(): void + { + if(this._isReady) return; + + if(!this._geometryReady || !this._partSetsReady || !this._actionsReady || !this._animationsReady || !this._figureMapReady || !this._effectMapReady || !this._structureReady) return; + + this._isReady = true; + + if(this.events) this.events.dispatchEvent(new NitroEvent(AvatarRenderEvent.AVATAR_RENDER_READY)); + } + + public createFigureContainer(figure: string): IAvatarFigureContainer + { + return new AvatarFigureContainer(figure); + } + + public isFigureContainerReady(container: IAvatarFigureContainer): boolean + { + if(!this._avatarAssetDownloadManager) return false; + + return this._avatarAssetDownloadManager.isAvatarFigureContainerReady(container); + } + + public createAvatarImage(figure: string, size: string, gender: string, listener: IAvatarImageListener = null, effectListener: IAvatarEffectListener = null): IAvatarImage + { + if(!this._structure || !this._avatarAssetDownloadManager) return null; + + const figureContainer = new AvatarFigureContainer(figure); + + if(gender) this.validateAvatarFigure(figureContainer, gender); + + if(this._avatarAssetDownloadManager.isAvatarFigureContainerReady(figureContainer)) + { + return new AvatarImage(this._structure, this._aliasCollection, figureContainer, size, this._effectAssetDownloadManager, effectListener); + } + + if(!this._placeHolderFigure) this._placeHolderFigure = new AvatarFigureContainer(AvatarRenderManager.DEFAULT_FIGURE); + + this._avatarAssetDownloadManager.downloadAvatarFigure(figureContainer, listener); + + return new PlaceHolderAvatarImage(this._structure, this._aliasCollection, this._placeHolderFigure, size, this._effectAssetDownloadManager); + } + + public downloadAvatarFigure(container: IAvatarFigureContainer, listener: IAvatarImageListener): void + { + if(!this._avatarAssetDownloadManager) return; + + this._avatarAssetDownloadManager.downloadAvatarFigure(container, listener); + } + + private validateAvatarFigure(container: AvatarFigureContainer, gender: string): boolean + { + let isValid = false; + + const typeIds = this._structure._Str_1733(gender, 2); + + if(typeIds) + { + const figureData = this._structure.figureData; + + for(const id of typeIds) + { + if(!container._Str_744(id)) + { + const figurePartSet = this._structure._Str_2264(id, gender); + + if(figurePartSet) + { + container._Str_830(id, figurePartSet.id, [0]); + + isValid = true; + } + } + else + { + const setType = figureData._Str_740(id); + + if(setType) + { + const figurePartSet = setType._Str_1020(container.getPartSetId(id)); + + if(!figurePartSet) + { + const partSet = this._structure._Str_2264(id, gender); + + if(partSet) + { + container._Str_830(id, partSet.id, [0]); + + isValid = true; + } + } + } + } + } + } + + return !(isValid); + } + + public getFigureClubLevel(container: IAvatarFigureContainer, gender: string, searchParts: string[]): number + { + if(!this._structure) return 0; + + const figureData = this._structure.figureData; + const parts = Array.from(container._Str_1016()); + + let clubLevel = 0; + + for(const part of parts) + { + const set = figureData._Str_740(part); + const setId = container.getPartSetId(part); + const partSet = set._Str_1020(setId); + + if(partSet) + { + clubLevel = Math.max(partSet.clubLevel, clubLevel); + + const palette = figureData._Str_783(set._Str_734); + const colors = container._Str_815(part); + + for(const colorId of colors) + { + const color = palette._Str_751(colorId); + + clubLevel = Math.max(color.clubLevel, clubLevel); + } + } + } + + if(!searchParts) searchParts = this._structure._Str_1695(AvatarSetType.FULL); + + for(const part of searchParts) + { + const set = figureData._Str_740(part); + + if(parts.indexOf(part) === -1) clubLevel = Math.max(set._Str_1002(gender), clubLevel); + } + + return clubLevel; + } + + public isValidFigureSetForGender(setId: number, gender: string): boolean + { + const structure = this.structureData; + const partSet = structure._Str_938(setId); + + return !!(partSet && ((partSet.gender.toUpperCase() === 'U') || (partSet.gender.toUpperCase() === gender.toUpperCase()))); + } + + public getFigureStringWithFigureIds(k: string, _arg_2: string, _arg_3: number[]): string + { + const container = new FigureDataContainer(); + + container._Str_2153(k, _arg_2); + + const partSets: IFigurePartSet[] = this._Str_1667(_arg_3); + + for(const partSet of partSets) + { + container._Str_2088(partSet.type, partSet.id, container.getColourIds(partSet.type)); + } + + return container._Str_1008(); + } + + private _Str_1667(k: number[]): IFigurePartSet[] + { + const structure = this.structureData; + const partSets: IFigurePartSet[] = []; + + for(const _local_4 of k) + { + const partSet = structure._Str_938(_local_4); + + if(partSet) partSets.push(partSet); + } + + return partSets; + } + + public _Str_838(k: string, _arg_2: number): string[] + { + if(!this._structure) return null; + + return this._structure._Str_1733(k, _arg_2); + } + + public getAssetByName(name: string): IGraphicAsset + { + return this._aliasCollection.getAsset(name); + } + + public get assets(): IAssetManager + { + return Nitro.instance.core.asset; + } + + public get isReady(): boolean + { + return this._isReady; + } + + public get structure(): AvatarStructure + { + return this._structure; + } + + public get structureData(): IStructureData + { + if(this._structure) return this._structure.figureData; + + return null; + } + + public get downloadManager(): AvatarAssetDownloadManager + { + return this._avatarAssetDownloadManager; + } +} diff --git a/src/nitro/avatar/AvatarStructure.ts b/src/nitro/avatar/AvatarStructure.ts new file mode 100644 index 00000000..4f6377e7 --- /dev/null +++ b/src/nitro/avatar/AvatarStructure.ts @@ -0,0 +1,653 @@ +import { Point } from 'pixi.js'; +import { IAssetManager } from '../../core/asset/IAssetManager'; +import { IAssetAnimation } from '../../core/asset/interfaces'; +import { EventDispatcher } from '../../core/events/EventDispatcher'; +import { ActionDefinition } from './actions/ActionDefinition'; +import { AvatarActionManager } from './actions/AvatarActionManager'; +import { IActionDefinition } from './actions/IActionDefinition'; +import { IActiveActionData } from './actions/IActiveActionData'; +import { Animation } from './animation/Animation'; +import { AnimationLayerData } from './animation/AnimationLayerData'; +import { AnimationManager } from './animation/AnimationManager'; +import { AvatarImagePartContainer } from './AvatarImagePartContainer'; +import { AvatarRenderManager } from './AvatarRenderManager'; +import { AvatarDirectionAngle } from './enum/AvatarDirectionAngle'; +import { AvatarModelGeometry } from './geometry/AvatarModelGeometry'; +import { IAvatarFigureContainer } from './IAvatarFigureContainer'; +import { IAvatarImage } from './IAvatarImage'; +import { IAvatarRenderManager } from './IAvatarRenderManager'; +import { AnimationAction } from './structure/animation/AnimationAction'; +import { AnimationFrame } from './structure/animation/AnimationFrame'; +import { AnimationData } from './structure/AnimationData'; +import { AvatarCanvas } from './structure/AvatarCanvas'; +import { IFigurePartSet } from './structure/figure/IFigurePartSet'; +import { IPartColor } from './structure/figure/IPartColor'; +import { FigureSetData } from './structure/FigureSetData'; +import { IStructureData } from './structure/IStructureData'; +import { PartSetsData } from './structure/PartSetsData'; + +export class AvatarStructure extends EventDispatcher +{ + private _renderManager: AvatarRenderManager; + private _geometry: AvatarModelGeometry; + private _figureData: FigureSetData; + private _partSetsData: PartSetsData; + private _animationData: AnimationData; + private _animationManager: AnimationManager; + private _mandatorySetTypeIds: { [index: string]: { [index: number]: string[] } }; + private _actionManager: AvatarActionManager; + private _defaultAction: IActionDefinition; + + constructor(renderManager: AvatarRenderManager) + { + super(); + + this._renderManager = renderManager; + this._geometry = null; + this._figureData = new FigureSetData(); + this._partSetsData = new PartSetsData(); + this._animationData = new AnimationData(); + this._animationManager = new AnimationManager(); + this._mandatorySetTypeIds = {}; + this._actionManager = null; + this._defaultAction = null; + } + + public init(): void + { + + } + + public dispose(): void + { + if(this.disposed) return; + + super.dispose(); + + this._renderManager = null; + this._figureData = null; + this._partSetsData = null; + this._animationData = null; + this._mandatorySetTypeIds = null; + } + + public _Str_1825(k: any): void + { + if(!k) return; + + this._geometry = new AvatarModelGeometry(k); + } + + public _Str_1060(k: IAssetManager, _arg_2: any): void + { + if(!_arg_2) return; + + this._actionManager = new AvatarActionManager(k, _arg_2); + this._defaultAction = this._actionManager._Str_1027(); + } + + public _Str_1620(data: any): void + { + this._actionManager._Str_1620(data); + + this._defaultAction = this._actionManager._Str_1027(); + } + + public _Str_1296(k: any): boolean + { + if(!k) return false; + + if(this._partSetsData.parse(k)) + { + this._partSetsData._Str_1102('ri')._Str_1583 = true; + this._partSetsData._Str_1102('li')._Str_1583 = true; + + return true; + } + + return false; + } + + public _Str_2229(k: any): boolean + { + if(!k) return false; + + return this._animationData.parse(k); + } + + public _Str_1569(k: any): boolean + { + if(!k) return false; + + return this._figureData.parse(k); + } + + public _Str_882(data: any): void + { + this._figureData._Str_1133(data); + } + + public _Str_1849(k: IAssetManager, _arg_2: string = 'fx', _arg_3: number = 200): void + { + let index = 0; + + while(index < _arg_3) + { + const collection = k.getCollection((_arg_2 + index)); + + if(collection) + { + const animationData = collection.data; + + this._animationManager._Str_2061(this, animationData.animations); + } + + index++; + } + } + + public _Str_2061(data: { [index: string]: IAssetAnimation }): void + { + this._animationManager._Str_2061(this, data); + } + + public _Str_867(k: IAvatarFigureContainer, _arg_2: string, _arg_3: number = 0): IPartColor + { + const _local_4 = k._Str_815(_arg_2); + + if((!(_local_4)) || (_local_4.length < _arg_3)) return null; + + const _local_5 = this._figureData._Str_740(_arg_2); + + if(_local_5 == null) return null; + + const _local_6 = this._figureData._Str_783(_local_5._Str_734); + + if(!_local_6) return null; + + return _local_6._Str_751(_local_4[_arg_3]); + } + + public _Str_1881(animation: string, frameCount: number, spriteId: string): AnimationLayerData + { + return this._animationManager._Str_607(animation, frameCount, spriteId) as AnimationLayerData; + } + + public _Str_720(k: string): Animation + { + return this._animationManager._Str_720(k) as Animation; + } + + public _Str_1675(k: string): ActionDefinition + { + return this._actionManager._Str_1675(k); + } + + public _Str_2018(k: string): ActionDefinition + { + return this._actionManager._Str_2018(k); + } + + public _Str_1939(k: string): boolean + { + return this._geometry._Str_1939(k); + } + + public _Str_711(k: IActiveActionData[]): IActiveActionData[] + { + return this._actionManager._Str_711(k); + } + + public _Str_1936(k: IActiveActionData[]): number + { + let _local_2 = 0; + + for(const _local_3 of k) + { + _local_2 = Math.max(_local_2, this._animationData._Str_1408(_local_3._Str_742)); + } + return _local_2; + } + + public _Str_1733(k: string, _arg_2: number): string[] + { + if(!this._mandatorySetTypeIds[k]) + { + this._mandatorySetTypeIds[k] = []; + } + + if(this._mandatorySetTypeIds[k][_arg_2]) + { + return this._mandatorySetTypeIds[k][_arg_2]; + } + + this._mandatorySetTypeIds[k][_arg_2] = this._figureData._Str_1733(k, _arg_2); + + return this._mandatorySetTypeIds[k][_arg_2]; + } + + public _Str_2264(k: string, _arg_2: string): IFigurePartSet + { + return this._figureData._Str_2264(k, _arg_2); + } + + public _Str_781(k: IActiveActionData[], _arg_2: string, _arg_3: number): number[] + { + return this._actionManager._Str_781(k, _arg_2, _arg_3); + } + + public _Str_1664(k: string, _arg_2: string): AvatarCanvas + { + return this._geometry._Str_1664(k, _arg_2); + } + + public _Str_2101(k: IAvatarImage): void + { + this._geometry._Str_2101(k); + } + + public _Str_2021(k: IActiveActionData, _arg_2: IAvatarImage): string[] + { + let _local_3: string[] = []; + + const _local_4: string[] = []; + const _local_5 = k._Str_742._Str_868; + + if(k._Str_742._Str_861) + { + const _local_7 = ((k._Str_742.state + '.') + k._Str_727); + const _local_8 = this._animationManager._Str_720(_local_7); + + if(_local_8) + { + _local_3 = _local_8._Str_1065(0, k._Str_707); + + if(_local_8._Str_706()) + { + const _local_11 = { + id: '', + x: 0, + y: 0, + z: 0, + radius: 0.01, + nx: 0, + ny: 0, + nz: -1, + double: 1 + }; + + const _local_12 = { + setType: '' + }; + + for(const _local_13 of _local_8._Str_687) + { + const _local_6 = this._geometry._Str_1919(_local_5, _local_13.align); + + if(_local_6) + { + _local_11.id = _local_13.id; + _local_6._Str_2020(_local_11, _arg_2); + + _local_12.setType = _local_13.id; + + const _local_10 = this._partSetsData._Str_1520(_local_12); + _local_10._Str_1583 = true; + + if(_local_13.base === '') _local_10._Str_1734 = 1; + + if(_local_4.indexOf(_local_6.id) === -1) _local_4.push(_local_6.id); + } + } + } + } + + for(const _local_9 of _local_3) + { + const _local_6 = this._geometry._Str_1919(_local_5, _local_9); + + if(_local_6 && (_local_4.indexOf(_local_6.id) === -1)) _local_4.push(_local_6.id); + } + } + else + { + _local_3 = this._partSetsData._Str_1795(k._Str_742); + + for(const _local_14 of _local_3) + { + const _local_6 = this._geometry._Str_1701(_local_5, _local_14, _arg_2); + + if(_local_6 && (_local_4.indexOf(_local_6.id) === -1)) _local_4.push(_local_6.id); + } + } + + return _local_4; + } + + public _Str_1695(k: string): string[] + { + return this._geometry._Str_1307(k); + } + + public _Str_755(k: string, _arg_2: string, _arg_3: number): string[] + { + const _local_4 = AvatarDirectionAngle.DIRECTION_TO_ANGLE[_arg_3]; + + return this._geometry._Str_2250(k, _local_4, _arg_2); + } + + public _Str_1888(k:IActiveActionData, _arg_2: number, _arg_3: number, _arg_4: string): Point + { + const _local_5 = this._animationData._Str_2244(k._Str_742); + + if(_local_5) return _local_5._Str_1888(_arg_2, _arg_3, _arg_4); + + return AnimationAction._Str_1934; + } + + public _Str_713(k: string, _arg_2:IAvatarFigureContainer, _arg_3:IActiveActionData, _arg_4: string, _arg_5: number, removes: string[], _arg_7: IAvatarImage, _arg_8: Map = null): AvatarImagePartContainer[] + { + const _local_10: Animation = null; + let _local_34: IActionDefinition = null; + + let _local_20: AnimationFrame[] = []; + let _local_36:IPartColor = null; + + if(!_arg_3 == null) return []; + + const _local_9 = this._partSetsData._Str_1795(_arg_3._Str_742); + const _local_11: AvatarImagePartContainer[] = []; + let _local_14: any[] = [ 0 ]; + const _local_15 = this._animationData._Str_2244(_arg_3._Str_742); + + if(_arg_3._Str_742._Str_861) + { + const _local_24 = ((_arg_3._Str_742.state + '.') + _arg_3._Str_727); + const _local_10 = this._animationManager._Str_720(_local_24); + + if(_local_10) + { + _local_14 = this._Str_1768(_local_10._Str_2185(_arg_3._Str_707)); + + for(const _local_25 of _local_10._Str_1065(0, _arg_3._Str_707)) + { + if(_local_25 === k) + { + const _local_26 = this._geometry._Str_1919(_arg_4, _local_25); + + if(_local_26) + { + for(const _local_27 of _local_26._Str_1883(_arg_7)) + { + _local_9.push(_local_27.id); + } + } + } + } + } + } + + const _local_16 = this._geometry._Str_713(_arg_4, k, _arg_5, _local_9, _arg_7); + const _local_21 = _arg_2._Str_1016(); + + for(const _local_17 of _local_21) + { + if(_arg_8) + { + if(_arg_8.get(_local_17)) continue; + } + + const _local_28 = _arg_2.getPartSetId(_local_17); + const _local_29 = _arg_2._Str_815(_local_17); + const _local_30 = this._figureData._Str_740(_local_17); + + + + if(_local_30) + { + const _local_31 = this._figureData._Str_783(_local_30._Str_734); + + if(_local_31) + { + const _local_32 = _local_30._Str_1020(_local_28); + + if(_local_32) + { + removes = removes.concat(_local_32._Str_790); + + for(const _local_33 of _local_32._Str_806) + { + if(_local_16.indexOf(_local_33.type) > -1) + { + if(_local_15) + { + const _local_19 = _local_15._Str_989(_local_33.type); + + if(_local_19) + { + _local_20 = _local_19.frames; + } + else + { + _local_20 = _local_14; + } + } + else + { + _local_20 = _local_14; + } + + _local_34 = _arg_3._Str_742; + + if(_local_9.indexOf(_local_33.type) === -1) _local_34 = this._defaultAction; + + const _local_13 = this._partSetsData._Str_1102(_local_33.type); + + let _local_35 = (!_local_13) ? _local_33.type : _local_13._Str_1693; + + if(!_local_35 || (_local_35 === '')) _local_35 = _local_33.type; + + if(_local_29 && (_local_29.length > (_local_33._Str_827 - 1))) + { + _local_36 = _local_31._Str_751(_local_29[(_local_33._Str_827 - 1)]); + } + + const _local_37 = (_local_33._Str_827 > 0); + const _local_18 = new AvatarImagePartContainer(k, _local_33.type, _local_33.id.toString(), _local_36, _local_20, _local_34, _local_37, _local_33.paletteMap, _local_35); + + _local_11.push(_local_18); + } + } + } + } + } + } + + const _local_22: AvatarImagePartContainer[] = []; + + for(const _local_12 of _local_16) + { + let _local_39: IPartColor = null; + let _local_38 = false; + + const _local_40 = ((_arg_8) && (_arg_8.get(_local_12))); + + for(const _local_23 of _local_11) + { + if(_local_23._Str_1669 === _local_12) + { + if(_local_40) + { + _local_39 = _local_23.color; + } + else + { + _local_38 = true; + + if(removes.indexOf(_local_12) === -1) _local_22.push(_local_23); + } + } + } + + if(!_local_38) + { + if(_local_40) + { + const _local_41 = _arg_8.get(_local_12); + + let _local_42 = 0; + let _local_43 = 0; + + while(_local_43 < _local_41.length) + { + _local_42 = (_local_42 + _local_41.charCodeAt(_local_43)); + _local_43++; + } + + if(_local_15) + { + const _local_19 = _local_15._Str_989(_local_12); + + if(_local_19) + { + _local_20 = _local_19.frames; + } + else + { + _local_20 = _local_14; + } + } + else + { + _local_20 = _local_14; + } + + const _local_18 = new AvatarImagePartContainer(k, _local_12, _local_41, _local_39, _local_20, _arg_3._Str_742, (!(_local_39 == null)), -1, _local_12, false, 1); + + _local_22.push(_local_18); + } + else + { + if(_local_9.indexOf(_local_12) > -1) + { + const _local_44 = this._geometry._Str_1701(_arg_4, _local_12, _arg_7); + + if(k !== _local_44.id) + { + // + } + else + { + const _local_13 = this._partSetsData._Str_1102(_local_12); + + let _local_45 = false; + let _local_46 = 1; + + if(_local_13._Str_1583) + { + let _local_47 = '1'; + + if(_arg_3._Str_727 !== '') + { + _local_47 = _arg_3._Str_727; + } + + if(_local_13._Str_2234()) + { + _local_47 = _local_13._Str_1734.toString(); + } + + if(_local_10 != null) + { + const _local_48 = _local_10._Str_1550(_local_12); + + if(_local_48) + { + _local_45 = _local_48._Str_1096; + _local_46 = _local_48.blend; + } + } + + if(_local_15) + { + const _local_19 = _local_15._Str_989(_local_12); + + if(_local_19) + { + _local_20 = _local_19.frames; + } + else + { + _local_20 = _local_14; + } + } + else + { + _local_20 = _local_14; + } + + const _local_18 = new AvatarImagePartContainer(k, _local_12, _local_47, null, _local_20, _arg_3._Str_742, false, -1, _local_12, _local_45, _local_46); + + _local_22.push(_local_18); + } + } + } + } + } + } + + return _local_22; + } + + private _Str_1768(k: number): number[] + { + const _local_2: number[] = []; + + let index = 0; + + while(index < k) + { + _local_2.push(index); + + index++; + } + + return _local_2; + } + + public _Str_672(): string[] + { + if(this._actionManager) + { + const k = this._actionManager._Str_1675('CarryItem').params; + + const _local_2 = []; + + for(const _local_3 of k.values()) _local_2.push(_local_3); + + return _local_2; + } + + return []; + } + + public get renderManager(): IAvatarRenderManager + { + return this._renderManager; + } + + public get figureData(): IStructureData + { + return this._figureData; + } + + public get partData(): PartSetsData + { + return this._partSetsData; + } + + public get animationManager(): AnimationManager + { + return this._animationManager; + } +} diff --git a/src/nitro/avatar/EffectAssetDownloadLibrary.ts b/src/nitro/avatar/EffectAssetDownloadLibrary.ts new file mode 100644 index 00000000..7899805d --- /dev/null +++ b/src/nitro/avatar/EffectAssetDownloadLibrary.ts @@ -0,0 +1,86 @@ +import { IAssetManager } from '../../core/asset/IAssetManager'; +import { IAssetAnimation } from '../../core/asset/interfaces'; +import { EventDispatcher } from '../../core/events/EventDispatcher'; +import { AvatarRenderEffectLibraryEvent } from './events/AvatarRenderEffectLibraryEvent'; + +export class EffectAssetDownloadLibrary extends EventDispatcher +{ + public static DOWNLOAD_COMPLETE: string = 'EADL_DOWNLOAD_COMPLETE'; + + private static NOT_LOADED: number = 0; + private static LOADING: number = 1; + private static LOADED: number = 2; + + private _state: number; + private _libraryName: string; + private _revision: string; + private _downloadUrl: string; + private _assets: IAssetManager; + private _animation: { [index: string]: IAssetAnimation }; + + constructor(id: string, revision: string, assets: IAssetManager, assetUrl: string) + { + super(); + + this._state = EffectAssetDownloadLibrary.NOT_LOADED; + this._libraryName = id; + this._revision = revision; + this._downloadUrl = assetUrl; + this._assets = assets; + this._animation = null; + + this._downloadUrl = this._downloadUrl.replace(/%libname%/gi, this._libraryName); + this._downloadUrl = this._downloadUrl.replace(/%revision%/gi, this._revision); + + const asset = this._assets.getCollection(this._libraryName); + + if(asset) this._state = EffectAssetDownloadLibrary.LOADED; + } + + public downloadAsset(): void + { + if(!this._assets || (this._state === EffectAssetDownloadLibrary.LOADING) || (this._state === EffectAssetDownloadLibrary.LOADED)) return; + + const asset = this._assets.getCollection(this._libraryName); + + if(asset) + { + this._state = EffectAssetDownloadLibrary.LOADED; + + this.dispatchEvent(new AvatarRenderEffectLibraryEvent(AvatarRenderEffectLibraryEvent.DOWNLOAD_COMPLETE, this)); + + return; + } + + this._state = EffectAssetDownloadLibrary.LOADING; + + this._assets.downloadAsset(this._downloadUrl, (flag: boolean) => + { + if(flag) + { + this._state = EffectAssetDownloadLibrary.LOADED; + + const collection = this._assets.getCollection(this._libraryName); + + if(collection) this._animation = collection.data.animations; + + this.dispatchEvent(new AvatarRenderEffectLibraryEvent(AvatarRenderEffectLibraryEvent.DOWNLOAD_COMPLETE, this)); + } + }); + } + + public get libraryName(): string + { + return this._libraryName; + } + + public get animation(): { [index: string]: IAssetAnimation } + { + return this._animation; + } + + public get isLoaded(): boolean + { + return (this._state === EffectAssetDownloadLibrary.LOADED); + } +} diff --git a/src/nitro/avatar/EffectAssetDownloadManager.ts b/src/nitro/avatar/EffectAssetDownloadManager.ts new file mode 100644 index 00000000..c34c03fd --- /dev/null +++ b/src/nitro/avatar/EffectAssetDownloadManager.ts @@ -0,0 +1,302 @@ +import { IAssetManager } from '../../core/asset/IAssetManager'; +import { NitroLogger } from '../../core/common/logger/NitroLogger'; +import { EventDispatcher } from '../../core/events/EventDispatcher'; +import { NitroEvent } from '../../core/events/NitroEvent'; +import { Nitro } from '../Nitro'; +import { AvatarStructure } from './AvatarStructure'; +import { EffectAssetDownloadLibrary } from './EffectAssetDownloadLibrary'; +import { AvatarRenderEffectLibraryEvent } from './events/AvatarRenderEffectLibraryEvent'; +import { AvatarRenderEvent } from './events/AvatarRenderEvent'; +import { IAvatarEffectListener } from './IAvatarEffectListener'; + +export class EffectAssetDownloadManager extends EventDispatcher +{ + public static DOWNLOADER_READY: string = 'EADM_DOWNLOADER_READY'; + public static LIBRARY_LOADED: string = 'EADM_LIBRARY_LOADED'; + + private static MAX_DOWNLOADS: number = 2; + + private _assets: IAssetManager; + private _structure: AvatarStructure; + + private _missingMandatoryLibs: string[]; + private _effectMap: Map; + private _initDownloadBuffer: [ number, IAvatarEffectListener][]; + private _effectListeners: Map; + private _incompleteEffects: Map; + private _pendingDownloadQueue: EffectAssetDownloadLibrary[]; + private _currentDownloads: EffectAssetDownloadLibrary[]; + private _libraryNames: string[]; + private _isReady: boolean; + + constructor(assets: IAssetManager, structure: AvatarStructure) + { + super(); + + this._assets = assets; + this._structure = structure; + + this._missingMandatoryLibs = Nitro.instance.getConfiguration('avatar.mandatory.effect.libraries'); + this._effectMap = new Map(); + this._effectListeners = new Map(); + this._incompleteEffects = new Map(); + this._initDownloadBuffer = []; + this._pendingDownloadQueue = []; + this._currentDownloads = []; + this._libraryNames = []; + this._isReady = false; + + this.onLibraryLoaded = this.onLibraryLoaded.bind(this); + this.onAvatarRenderReady = this.onAvatarRenderReady.bind(this); + + this.loadEffectMap(); + + this._structure.renderManager.events.addEventListener(AvatarRenderEvent.AVATAR_RENDER_READY, this.onAvatarRenderReady); + } + + private loadEffectMap(): void + { + const request = new XMLHttpRequest(); + + try + { + request.open('GET', Nitro.instance.getConfiguration('avatar.effectmap.url')); + + request.send(); + + request.onloadend = e => + { + if(request.responseText) + { + const data = JSON.parse(request.responseText); + + this.processEffectMap(data.effects); + + this.processMissingLibraries(); + + this._isReady = true; + + this.dispatchEvent(new NitroEvent(EffectAssetDownloadManager.DOWNLOADER_READY)); + } + }; + + request.onerror = e => + { + throw new Error('invalid_avatar_effect_map'); + }; + } + + catch (e) + { + NitroLogger.log(e); + } + } + + private processEffectMap(data: any): void + { + if(!data) return; + + for(const effect of data) + { + if(!effect) continue; + + const id = (effect.id as string); + const lib = (effect.lib as string); + const revision = (effect.revision || ''); + + if(this._libraryNames.indexOf(lib) >= 0) continue; + + this._libraryNames.push(lib); + + const downloadLibrary = new EffectAssetDownloadLibrary(lib, revision, this._assets, Nitro.instance.getConfiguration('avatar.asset.effect.url')); + + downloadLibrary.addEventListener(AvatarRenderEffectLibraryEvent.DOWNLOAD_COMPLETE, this.onLibraryLoaded); + + let existing = this._effectMap.get(id); + + if(!existing) existing = []; + + existing.push(downloadLibrary); + + this._effectMap.set(id, existing); + } + } + + public downloadAvatarEffect(id: number, listener: IAvatarEffectListener): void + { + if(!this._isReady || !this._structure.renderManager.isReady) + { + this._initDownloadBuffer.push([ id, listener ]); + + return; + } + + const pendingLibraries = this.getAvatarEffectPendingLibraries(id); + + if(pendingLibraries && pendingLibraries.length) + { + if(listener && !listener.disposed) + { + let listeners = this._effectListeners.get(id.toString()); + + if(!listeners) listeners = []; + + listeners.push(listener); + + this._effectListeners.set(id.toString(), listeners); + } + + this._incompleteEffects.set(id.toString(), pendingLibraries); + + for(const library of pendingLibraries) + { + if(!library) continue; + + this.downloadLibrary(library); + } + } + else + { + if(listener && !listener.disposed) listener.resetEffect(id); + } + } + + private onAvatarRenderReady(event: NitroEvent): void + { + if(!event) return; + + for(const [ id, listener ] of this._initDownloadBuffer) + { + this.downloadAvatarEffect(id, listener); + } + + this._initDownloadBuffer = []; + } + + private onLibraryLoaded(event: AvatarRenderEffectLibraryEvent): void + { + if(!event || !event.library) return; + + const loadedEffects: string[] = []; + + this._structure._Str_2061(event.library.animation); + + for(const [ id, libraries ] of this._incompleteEffects.entries()) + { + let isReady = true; + + for(const library of libraries) + { + if(!library || library.isLoaded) continue; + + isReady = false; + + break; + } + + if(isReady) + { + loadedEffects.push(id); + + const listeners = this._effectListeners.get(id); + + for(const listener of listeners) + { + if(!listener || listener.disposed) continue; + + listener.resetEffect(parseInt(id)); + } + + this._effectListeners.delete(id); + + this.dispatchEvent(new NitroEvent(EffectAssetDownloadManager.LIBRARY_LOADED)); + } + } + + for(const id of loadedEffects) this._incompleteEffects.delete(id); + + let index = 0; + + while(index < this._currentDownloads.length) + { + const download = this._currentDownloads[index]; + + if(download) + { + if(download.libraryName === event.library.libraryName) this._currentDownloads.splice(index, 1); + } + + index++; + } + } + + public processMissingLibraries(): void + { + const libraries = this._missingMandatoryLibs.slice(); + + for(const library of libraries) + { + if(!library) continue; + + const map = this._effectMap.get(library); + + if(map) for(const effect of map) effect && this.downloadLibrary(effect); + } + } + + public isAvatarEffectReady(effect: number): boolean + { + if(!this._isReady || !this._structure.renderManager.isReady) + { + return false; + } + + const pendingLibraries = this.getAvatarEffectPendingLibraries(effect); + + return !pendingLibraries.length; + } + + private getAvatarEffectPendingLibraries(id: number): EffectAssetDownloadLibrary[] + { + const pendingLibraries: EffectAssetDownloadLibrary[] = []; + + if(!this._structure) return pendingLibraries; + + const libraries = this._effectMap.get(id.toString()); + + if(libraries) + { + for(const library of libraries) + { + if(!library || library.isLoaded) continue; + + if(pendingLibraries.indexOf(library) === -1) pendingLibraries.push(library); + } + } + + return pendingLibraries; + } + + private downloadLibrary(library: EffectAssetDownloadLibrary): void + { + if(!library || library.isLoaded) return; + + if((this._pendingDownloadQueue.indexOf(library) >= 0) || (this._currentDownloads.indexOf(library) >= 0)) return; + + this._pendingDownloadQueue.push(library); + + this.processDownloadQueue(); + } + + private processDownloadQueue(): void + { + while(this._pendingDownloadQueue.length) + { + const library = this._pendingDownloadQueue[0]; + + library.downloadAsset(); + + this._currentDownloads.push(this._pendingDownloadQueue.shift()); + } + } +} diff --git a/src/nitro/avatar/IAvatarEffectListener.ts b/src/nitro/avatar/IAvatarEffectListener.ts new file mode 100644 index 00000000..c0fd5cf3 --- /dev/null +++ b/src/nitro/avatar/IAvatarEffectListener.ts @@ -0,0 +1,6 @@ +import { IDisposable } from '../../core/common/disposable/IDisposable'; + +export interface IAvatarEffectListener extends IDisposable +{ + resetEffect(effect: number): void; +} \ No newline at end of file diff --git a/src/nitro/avatar/IAvatarFigureContainer.ts b/src/nitro/avatar/IAvatarFigureContainer.ts new file mode 100644 index 00000000..4a9cbbb3 --- /dev/null +++ b/src/nitro/avatar/IAvatarFigureContainer.ts @@ -0,0 +1,10 @@ +export interface IAvatarFigureContainer +{ + _Str_1016(): IterableIterator; + _Str_744(_arg_1: string): boolean; + getPartSetId(_arg_1: string): number; + _Str_815(_arg_1: string): number[]; + _Str_830(_arg_1: string, _arg_2: number, _arg_3: number[]): void; + _Str_923(_arg_1: string): void; + _Str_1008(): string; +} \ No newline at end of file diff --git a/src/nitro/avatar/IAvatarImage.ts b/src/nitro/avatar/IAvatarImage.ts new file mode 100644 index 00000000..b88bade6 --- /dev/null +++ b/src/nitro/avatar/IAvatarImage.ts @@ -0,0 +1,37 @@ +import { RenderTexture, Sprite } from 'pixi.js'; +import { IDisposable } from '../../core/common/disposable/IDisposable'; +import { IGraphicAsset } from '../../room/object/visualization/utils/IGraphicAsset'; +import { IAnimationLayerData } from './animation/IAnimationLayerData'; +import { IAvatarDataContainer } from './animation/IAvatarDataContainer'; +import { ISpriteDataContainer } from './animation/ISpriteDataContainer'; +import { IAvatarFigureContainer } from './IAvatarFigureContainer'; +import { IPartColor } from './structure/figure/IPartColor'; + +export interface IAvatarImage extends IDisposable +{ + getServerRenderData(): any; + setDirection(_arg_1: string, _arg_2: number): void; + setDirectionAngle(_arg_1: string, _arg_2: number): void; + updateAnimationByFrames(_arg_1?: number): void; + getScale(): string; + getSprites(): ISpriteDataContainer[]; + getLayerData(_arg_1: ISpriteDataContainer): IAnimationLayerData; + getImage(setType: string, hightlight: boolean, scale?: number, cache?: boolean): RenderTexture; + getImageAsSprite(setType: string, scale?: number): Sprite; + getCroppedImage(setType: string, scale?: number): HTMLImageElement; + getAsset(_arg_1: string): IGraphicAsset; + getDirection(): number; + getFigure(): IAvatarFigureContainer; + getPartColor(_arg_1: string): IPartColor; + isAnimating(): boolean; + getCanvasOffsets(): number[]; + initActionAppends(): void; + endActionAppends(): void; + appendAction(_arg_1: string, ..._args: any[]): boolean; + avatarSpriteData: IAvatarDataContainer; + isPlaceholder(): boolean; + forceActionUpdate(): void; + animationHasResetOnToggle: boolean; + resetAnimationFrameCounter(): void; + mainAction: string; +} \ No newline at end of file diff --git a/src/nitro/avatar/IAvatarImageListener.ts b/src/nitro/avatar/IAvatarImageListener.ts new file mode 100644 index 00000000..9a0b0ddf --- /dev/null +++ b/src/nitro/avatar/IAvatarImageListener.ts @@ -0,0 +1,6 @@ +import { IDisposable } from '../../core/common/disposable/IDisposable'; + +export interface IAvatarImageListener extends IDisposable +{ + resetFigure(figure: string): void; +} diff --git a/src/nitro/avatar/IAvatarRenderManager.ts b/src/nitro/avatar/IAvatarRenderManager.ts new file mode 100644 index 00000000..ac3f3fed --- /dev/null +++ b/src/nitro/avatar/IAvatarRenderManager.ts @@ -0,0 +1,28 @@ +import { IAssetManager } from '../../core/asset/IAssetManager'; +import { INitroManager } from '../../core/common/INitroManager'; +import { IGraphicAsset } from '../../room/object/visualization/utils/IGraphicAsset'; +import { AvatarAssetDownloadManager } from './AvatarAssetDownloadManager'; +import { AvatarStructure } from './AvatarStructure'; +import { IAvatarEffectListener } from './IAvatarEffectListener'; +import { IAvatarFigureContainer } from './IAvatarFigureContainer'; +import { IAvatarImage } from './IAvatarImage'; +import { IAvatarImageListener } from './IAvatarImageListener'; +import { IStructureData } from './structure/IStructureData'; + +export interface IAvatarRenderManager extends INitroManager +{ + createFigureContainer(figure: string): IAvatarFigureContainer; + isFigureContainerReady(container: IAvatarFigureContainer): boolean; + createAvatarImage(figure: string, size: string, gender: string, listener?: IAvatarImageListener, effectListener?: IAvatarEffectListener): IAvatarImage; + downloadAvatarFigure(container: IAvatarFigureContainer, listener: IAvatarImageListener): void; + getFigureClubLevel(container: IAvatarFigureContainer, gender: string, searchParts: string[]): number; + isValidFigureSetForGender(setId: number, gender: string): boolean; + getFigureStringWithFigureIds(k: string, _arg_2: string, _arg_3: number[]): string; + _Str_838(k: string, _arg_2: number): string[]; + getAssetByName(name: string): IGraphicAsset; + assets: IAssetManager; + isReady: boolean; + structure: AvatarStructure; + structureData: IStructureData; + downloadManager: AvatarAssetDownloadManager; +} \ No newline at end of file diff --git a/src/nitro/avatar/IOutfit.ts b/src/nitro/avatar/IOutfit.ts new file mode 100644 index 00000000..e797d6ff --- /dev/null +++ b/src/nitro/avatar/IOutfit.ts @@ -0,0 +1,5 @@ +export interface IOutfit +{ + figure: string; + gender: string; +} \ No newline at end of file diff --git a/src/nitro/avatar/PlaceHolderAvatarImage.ts b/src/nitro/avatar/PlaceHolderAvatarImage.ts new file mode 100644 index 00000000..15847812 --- /dev/null +++ b/src/nitro/avatar/PlaceHolderAvatarImage.ts @@ -0,0 +1,18 @@ +import { AssetAliasCollection } from './alias/AssetAliasCollection'; +import { AvatarFigureContainer } from './AvatarFigureContainer'; +import { AvatarImage } from './AvatarImage'; +import { AvatarStructure } from './AvatarStructure'; +import { EffectAssetDownloadManager } from './EffectAssetDownloadManager'; + +export class PlaceHolderAvatarImage extends AvatarImage +{ + constructor(k: AvatarStructure, _arg_2: AssetAliasCollection, _arg_3: AvatarFigureContainer, _arg_4: string, _arg_5: EffectAssetDownloadManager) + { + super(k, _arg_2, _arg_3, _arg_4, _arg_5, null); + } + + public isPlaceholder(): boolean + { + return true; + } +} \ No newline at end of file diff --git a/src/nitro/avatar/actions/ActionDefinition.ts b/src/nitro/avatar/actions/ActionDefinition.ts new file mode 100644 index 00000000..df5b4b52 --- /dev/null +++ b/src/nitro/avatar/actions/ActionDefinition.ts @@ -0,0 +1,224 @@ +import { ActionType } from './ActionType'; +import { IActionDefinition } from './IActionDefinition'; + +export class ActionDefinition implements IActionDefinition +{ + private _id: string; + private _state: string; + private _precedence: number; + private _activePartSet: string; + private _assetPartDefinition: string; + private _lay: string; + private _geometryType: string; + private _isMain: boolean; + private _isDefault: boolean; + private _isAnimation: boolean; + private _startFromFrameZero: boolean; + private _prevents: string[]; + private _preventHeadTurn: boolean; + private _types: Map; + private _params: Map; + private _defaultParameterValue: string; + private _canvasOffsets: Map>; + + constructor(data: any) + { + this._id = data.id; + this._state = data.state; + this._precedence = data.precedence; + this._activePartSet = data.activePartSet; + this._assetPartDefinition = data.assetPartDefinition; + this._lay = data.lay; + this._geometryType = data.geometryType; + this._isMain = data.main || false; + this._isDefault = data.isDefault || false; + this._isAnimation = data.animation || false; + this._startFromFrameZero = data.startFromFrameZero || false; + this._prevents = data.prevents || []; + this._preventHeadTurn = data.preventHeadTurn || false; + this._types = new Map(); + this._params = new Map(); + this._defaultParameterValue = ''; + this._canvasOffsets = null; + + if(data.params && (data.params.length > 0)) + { + for(const param of data.params) + { + if(!param) continue; + + if(param.id === 'default') this._defaultParameterValue = param.value; + else this._params.set(param.id, param.value); + } + } + + if(data.types && (data.types.length > 0)) + { + for(const type of data.types) + { + if(!type) continue; + + const action = new ActionType(type); + + this._types.set(action.id, action); + } + } + } + + public _Str_772(k: string, _arg_2: number, _arg_3: number[]): void + { + if(!this._canvasOffsets) this._canvasOffsets = new Map(); + + let existing = this._canvasOffsets.get(k); + + if(!existing) + { + existing = new Map(); + + this._canvasOffsets.set(k, existing); + } + + existing.set(_arg_2, _arg_3); + } + + public _Str_805(k: string, _arg_2: number): number[] + { + if(!this._canvasOffsets) return null; + + const existing = this._canvasOffsets.get(k); + + if(!existing) return null; + + return existing.get(_arg_2); + } + + public getType(id: string): ActionType + { + if(!id) return null; + + const existing = this._types.get(parseInt(id)); + + if(!existing) return null; + + return existing; + } + + public _Str_1350(id: string): string + { + if(!id) return ''; + + const existing = this._params.get(id); + + if(!existing) return this._defaultParameterValue; + + return existing; + } + + public _Str_733(type: string): string[] + { + return this._prevents.concat(this._Str_1889(type)); + } + + private _Str_1889(type: string): string[] + { + if(!type) return []; + + const existing = this._types.get(parseInt(type)); + + if(!existing) return []; + + return existing.prevents; + } + + public _Str_715(k: string): boolean + { + if(!k) return this._preventHeadTurn; + + const type = this.getType(k); + + if(!type) return this._preventHeadTurn; + + return type._Str_1891; + } + + public _Str_801(k: string): boolean + { + if(!k) return true; + + const type = this.getType(k); + + if(!type) return true; + + return type._Str_801; + } + + public get id(): string + { + return this._id; + } + + public get state(): string + { + return this._state; + } + + public get precedence(): number + { + return this._precedence; + } + + public get activePartSet(): string + { + return this._activePartSet; + } + + public get _Str_778(): string + { + return this._assetPartDefinition; + } + + public get lay(): string + { + return this._lay; + } + + public get _Str_868(): string + { + return this._geometryType; + } + + public get _Str_779(): boolean + { + return this._isMain; + } + + public get _Str_804(): boolean + { + return this._isDefault; + } + + public get _Str_861(): boolean + { + return this._isAnimation; + } + + public get _Str_812(): boolean + { + return this._startFromFrameZero; + } + + public get prevents(): string[] + { + return this._prevents; + } + + public get preventHeadTurn(): boolean + { + return this._preventHeadTurn; + } + + public get params(): Map + { + return this._params; + } +} \ No newline at end of file diff --git a/src/nitro/avatar/actions/ActionType.ts b/src/nitro/avatar/actions/ActionType.ts new file mode 100644 index 00000000..5694bb1f --- /dev/null +++ b/src/nitro/avatar/actions/ActionType.ts @@ -0,0 +1,44 @@ +export class ActionType +{ + private _id: number; + private _value: number; + private _prevents: string[]; + private _preventHeadTurn: boolean; + private _isAnimated: boolean; + + constructor(data: any) + { + this._id = parseInt(data.id); + this._value = parseInt(data.id); + this._prevents = data.prevents || []; + this._preventHeadTurn = data.preventHeadTurn || false; + this._isAnimated = true; + + if((data.animated !== undefined) && (data.animated === false)) this._isAnimated = false; + } + + public get id(): number + { + return this._id; + } + + public get value(): number + { + return this._value; + } + + public get prevents(): string[] + { + return this._prevents; + } + + public get _Str_1891(): boolean + { + return this._preventHeadTurn; + } + + public get _Str_801(): boolean + { + return this._isAnimated; + } +} \ No newline at end of file diff --git a/src/nitro/avatar/actions/ActiveActionData.ts b/src/nitro/avatar/actions/ActiveActionData.ts new file mode 100644 index 00000000..7e2ce117 --- /dev/null +++ b/src/nitro/avatar/actions/ActiveActionData.ts @@ -0,0 +1,74 @@ +import { IActionDefinition } from './IActionDefinition'; +import { IActiveActionData } from './IActiveActionData'; + +export class ActiveActionData implements IActiveActionData +{ + private _actionType: string; + private _actionParameter: string; + private _definition: IActionDefinition; + private _startFrame: number; + private _overridingAction: string; + + constructor(action: string, parameter: string = '', startFrame: number = 0) + { + this._actionType = action || ''; + this._actionParameter = parameter || ''; + this._definition = null; + this._startFrame = startFrame || 0; + this._overridingAction = null; + } + + public dispose(): void + { + this._actionType = null; + this._actionParameter = null; + this._definition = null; + } + + public get id(): string + { + if(!this._definition) return ''; + + return this._definition.id + '_' + this._actionParameter; + } + + public get _Str_695(): string + { + return this._actionType; + } + + public get _Str_727(): string + { + return this._actionParameter; + } + + public set _Str_727(parameter: string) + { + this._actionParameter = parameter; + } + + public get _Str_742(): IActionDefinition + { + return this._definition; + } + + public set _Str_742(definition: IActionDefinition) + { + this._definition = definition; + } + + public get _Str_664(): number + { + return this._startFrame; + } + + public get _Str_707(): string + { + return this._overridingAction; + } + + public set _Str_707(action: string) + { + this._overridingAction = action; + } +} \ No newline at end of file diff --git a/src/nitro/avatar/actions/AvatarActionManager.ts b/src/nitro/avatar/actions/AvatarActionManager.ts new file mode 100644 index 00000000..6f56586c --- /dev/null +++ b/src/nitro/avatar/actions/AvatarActionManager.ts @@ -0,0 +1,187 @@ +import { IAssetManager } from '../../../core/asset/IAssetManager'; +import { ActionDefinition } from './ActionDefinition'; +import { IActiveActionData } from './IActiveActionData'; + +export class AvatarActionManager +{ + private _assets: IAssetManager; + private _actions: Map; + private _defaultAction: ActionDefinition; + + constructor(k: IAssetManager, data: any) + { + this._assets = k; + this._actions = new Map(); + this._defaultAction = null; + + this._Str_1620(data); + } + + public _Str_1620(data: any): void + { + if(!data) return; + + for(const action of data.actions) + { + if(!action || !action.state) continue; + + const definition = new ActionDefinition(action); + + this._actions.set(definition.state, definition); + } + + if(data.actionOffsets) this._Str_1767(data.actionOffsets); + } + + private _Str_1767(offsets: any): void + { + if(!offsets || !offsets.length) return; + + for(const offset of offsets) + { + const action = this._actions.get(offset.action); + + if(!action) continue; + + for(const canvasOffset of offset.offsets) + { + const size = (canvasOffset.size || ''); + const direction = canvasOffset.direction; + + if((size === '') || (direction === undefined)) continue; + + const x = (canvasOffset.x || 0); + const y = (canvasOffset.y || 0); + const z = (canvasOffset.z || 0); + + action._Str_772(size, direction, [ x, y, z ]); + } + } + } + + public _Str_1675(id: string): ActionDefinition + { + if(!id) return null; + + for(const action of this._actions.values()) + { + if(!action || (action.id !== id)) continue; + + return action; + } + + return null; + } + + public _Str_2018(state: string): ActionDefinition + { + const existing = this._actions.get(state); + + if(!existing) return null; + + return existing; + } + + public _Str_1027(): ActionDefinition + { + if(this._defaultAction) return this._defaultAction; + + for(const action of this._actions.values()) + { + if(!action || !action._Str_804) continue; + + this._defaultAction = action; + + return action; + } + + return null; + } + + public _Str_781(k: IActiveActionData[], _arg_2: string, _arg_3: number): number[] + { + let canvasOffsets: number[] = []; + + for(const activeAction of k) + { + if(!activeAction) continue; + + const action = this._actions.get(activeAction._Str_695); + const offsets = action && action._Str_805(_arg_2, _arg_3); + + if(offsets) canvasOffsets = offsets; + } + + return canvasOffsets; + } + + public _Str_711(actions: IActiveActionData[]): IActiveActionData[] + { + if(!actions) return null; + + actions = this._Str_1247(actions); + + const validatedActions: IActiveActionData[] = []; + + for(const action of actions) + { + if(!action) continue; + + const definition = this._actions.get(action._Str_695); + + if(!definition) continue; + + action._Str_742 = definition; + + validatedActions.push(action); + } + + validatedActions.sort(this.sortByPrecedence); + + return validatedActions; + } + + private _Str_1247(actions: IActiveActionData[]): IActiveActionData[] + { + let preventions: string[] = []; + const activeActions: IActiveActionData[] = []; + + for(const action of actions) + { + if(!action) continue; + + const localAction = this._actions.get(action._Str_695); + + if(localAction) preventions = preventions.concat(localAction._Str_733(action._Str_727)); + } + + for(const action of actions) + { + if(!action) continue; + + let actionType = action._Str_695; + + if(action._Str_695 === 'fx') actionType = (actionType + ('.' + action._Str_727)); + + if(preventions.indexOf(actionType) >= 0) continue; + + activeActions.push(action); + } + + return activeActions; + } + + private sortByPrecedence(actionOne: IActiveActionData, actionTwo: IActiveActionData): number + { + if(!actionOne || !actionTwo) return 0; + + const precedenceOne = actionOne._Str_742.precedence; + const precedenceTwo = actionTwo._Str_742.precedence; + + if(precedenceOne < precedenceTwo) return 1; + + if(precedenceOne > precedenceTwo) return -1; + + return 0; + } +} \ No newline at end of file diff --git a/src/nitro/avatar/actions/IActionDefinition.ts b/src/nitro/avatar/actions/IActionDefinition.ts new file mode 100644 index 00000000..a2edafb0 --- /dev/null +++ b/src/nitro/avatar/actions/IActionDefinition.ts @@ -0,0 +1,20 @@ + +export interface IActionDefinition +{ + id: string; + state: string; + precedence: number; + activePartSet: string; + _Str_779: boolean; + _Str_804: boolean; + _Str_778: string; + lay: string; + _Str_868: string; + _Str_861: boolean; + _Str_812: boolean; + _Str_801(_arg_1: string): boolean; + _Str_733(_arg_1: string): string[]; + _Str_715(_arg_1: string): boolean; + _Str_772(_arg_1: string, _arg_2: number, _arg_3: []): void; + _Str_805(_arg_1: string, _arg_2: number): number[]; +} \ No newline at end of file diff --git a/src/nitro/avatar/actions/IActiveActionData.ts b/src/nitro/avatar/actions/IActiveActionData.ts new file mode 100644 index 00000000..1e6bacc7 --- /dev/null +++ b/src/nitro/avatar/actions/IActiveActionData.ts @@ -0,0 +1,11 @@ +import { IActionDefinition } from './IActionDefinition'; + +export interface IActiveActionData +{ + id: string; + _Str_695: string; + _Str_727: string; + _Str_664: number; + _Str_742: IActionDefinition; + _Str_707: string; +} \ No newline at end of file diff --git a/src/nitro/avatar/alias/AssetAlias.ts b/src/nitro/avatar/alias/AssetAlias.ts new file mode 100644 index 00000000..99da1e1d --- /dev/null +++ b/src/nitro/avatar/alias/AssetAlias.ts @@ -0,0 +1,37 @@ +import { IAssetAlias } from '../../../core/asset/interfaces'; + +export class AssetAlias +{ + private _name: string; + private _link: string; + private _flipH: boolean; + private _flipV: boolean; + + constructor(name: string, alias: IAssetAlias) + { + this._name = name; + this._link = alias.link; + this._flipH = alias.flipH; + this._flipV = alias.flipV; + } + + public get name(): string + { + return this._name; + } + + public get link(): string + { + return this._link; + } + + public get flipH(): boolean + { + return this._flipH; + } + + public get flipV(): boolean + { + return this._flipV; + } +} diff --git a/src/nitro/avatar/alias/AssetAliasCollection.ts b/src/nitro/avatar/alias/AssetAliasCollection.ts new file mode 100644 index 00000000..85b2f009 --- /dev/null +++ b/src/nitro/avatar/alias/AssetAliasCollection.ts @@ -0,0 +1,90 @@ +import { IAssetManager } from '../../../core/asset/IAssetManager'; +import { IGraphicAsset } from '../../../room/object/visualization/utils/IGraphicAsset'; +import { AvatarRenderManager } from '../AvatarRenderManager'; +import { AssetAlias } from './AssetAlias'; + +export class AssetAliasCollection +{ + private _assets: IAssetManager; + private _aliases: Map; + private _avatarRenderManager: AvatarRenderManager; + private _missingAssetNames: string[]; + + constructor(k: AvatarRenderManager, _arg_2: IAssetManager) + { + this._avatarRenderManager = k; + this._aliases = new Map(); + this._assets = _arg_2; + this._missingAssetNames = []; + } + + public dispose(): void + { + this._assets = null; + this._aliases = null; + } + + public reset(): void + { + this.init(); + } + + public init(): void + { + for(const collection of this._assets.collections.values()) + { + if(!collection) continue; + + const aliases = collection.data && collection.data.aliases; + + if(!aliases) continue; + + for(const name in aliases) + { + const alias = aliases[name]; + + if(!alias) continue; + + this._aliases.set(name, new AssetAlias(name, alias)); + } + } + } + + public _Str_1044(k: string): boolean + { + const alias = this._aliases.get(k); + + if(alias) return true; + + return false; + } + + public _Str_2125(k: string): string + { + let _local_2 = k; + let _local_3 = 5; + + while(this._Str_1044(_local_2) && (_local_3 >= 0)) + { + const _local_4 = this._aliases.get(_local_2); + + _local_2 = _local_4.link; + _local_3--; + } + + return _local_2; + } + + public getAsset(name: string): IGraphicAsset + { + if(!this._assets) return null; + + name = this._Str_2125(name); + + const asset = this._assets.getAsset(name); + + if(!asset) return null; + + return asset; + } +} \ No newline at end of file diff --git a/src/nitro/avatar/animation/AddDataContainer.ts b/src/nitro/avatar/animation/AddDataContainer.ts new file mode 100644 index 00000000..5320b45b --- /dev/null +++ b/src/nitro/avatar/animation/AddDataContainer.ts @@ -0,0 +1,61 @@ +import { IAssetAnimationAdd } from '../../../core/asset/interfaces'; + +export class AddDataContainer +{ + private _id: string; + private _align: string; + private _base: string; + private _ink: number; + private _blend: number; + + constructor(k: IAssetAnimationAdd) + { + this._id = k.id || ''; + this._align = k.align || ''; + this._base = k.base || ''; + this._ink = k.ink || 0; + this._blend = 0; + + const _local_2 = k.blend; + + if(_local_2) + { + if(_local_2.length > 0) + { + this._blend = parseInt(_local_2); + + if(this._blend > 1) this._blend = (this._blend / 100); + } + } + } + + public get id(): string + { + return this._id; + } + + public get align(): string + { + return this._align; + } + + public get base(): string + { + return this._base; + } + + public get ink(): number + { + return this._ink; + } + + public get blend(): number + { + return this._blend; + } + + public get _Str_1096(): boolean + { + return this._blend !== 1; + } +} diff --git a/src/nitro/avatar/animation/Animation.ts b/src/nitro/avatar/animation/Animation.ts new file mode 100644 index 00000000..43d4bac8 --- /dev/null +++ b/src/nitro/avatar/animation/Animation.ts @@ -0,0 +1,312 @@ +import { IAssetAnimation, IAssetAnimationFrame } from '../../../core/asset/interfaces'; +import { AvatarStructure } from '../AvatarStructure'; +import { AddDataContainer } from './AddDataContainer'; +import { AnimationLayerData } from './AnimationLayerData'; +import { AvatarDataContainer } from './AvatarDataContainer'; +import { DirectionDataContainer } from './DirectionDataContainer'; +import { IAnimation } from './IAnimation'; +import { SpriteDataContainer } from './SpriteDataContainer'; + +export class Animation implements IAnimation +{ + private static _Str_2211: any[] = []; + + private _id: string; + private _description: string; + private _frames: AnimationLayerData[][]; + private _spriteData: SpriteDataContainer[]; + private _avatarData: AvatarDataContainer; + private _directionData: DirectionDataContainer; + private _removeData: string[]; + private _addData: AddDataContainer[]; + private _overriddenActions: Map; + private _overrideFrames: Map; + private _resetOnToggle: boolean; + + constructor(k: AvatarStructure, _arg_2: IAssetAnimation) + { + this._id = _arg_2.name; + this._description = this._id; + this._frames = []; + this._spriteData = null; + this._avatarData = null; + this._directionData = null; + this._removeData = null; + this._addData = null; + this._overriddenActions = null; + this._overrideFrames = null; + this._resetOnToggle = (_arg_2.resetOnToggle || false); + + if(_arg_2.sprites && _arg_2.sprites.length) + { + this._spriteData = []; + + for(const sprite of _arg_2.sprites) this._spriteData.push(new SpriteDataContainer(this, sprite)); + } + + if(_arg_2.avatars && _arg_2.avatars.length) this._avatarData = new AvatarDataContainer(_arg_2.avatars[0]); + + if(_arg_2.directions && _arg_2.directions.length) this._directionData = new DirectionDataContainer(_arg_2.directions[0]); + + if(_arg_2.removes && _arg_2.removes.length) + { + this._removeData = []; + + for(const remove of _arg_2.removes) this._removeData.push(remove.id); + } + + if(_arg_2.adds && _arg_2.adds.length) + { + this._addData = []; + + for(const add of _arg_2.adds) this._addData.push(new AddDataContainer(add)); + } + + if(_arg_2.overrides && _arg_2.overrides.length) + { + this._overrideFrames = new Map(); + this._overriddenActions = new Map(); + + for(const override of _arg_2.overrides) + { + const name = override.name; + const value = override.override; + + this._overriddenActions.set(value, name); + + const frames: AnimationLayerData[][] = []; + + this._Str_1031(frames, override.frames, k); + + this._overrideFrames.set(name, frames); + } + } + + this._Str_1031(this._frames, _arg_2.frames, k); + } + + private _Str_1031(frames: AnimationLayerData[][], _arg_2: IAssetAnimationFrame[], _arg_3: AvatarStructure): void + { + if(!_arg_2 || !_arg_2.length) return; + + for(const frame of _arg_2) + { + let repeats = 1; + + if(frame.repeats && (frame.repeats > 1)) repeats = frame.repeats; + + let index = 0; + + while(index < repeats) + { + const layers: AnimationLayerData[] = []; + + if(frame.bodyparts && frame.bodyparts.length) + { + for(const bodyPart of frame.bodyparts) + { + const definition = _arg_3._Str_1675(bodyPart.action); + const layer = new AnimationLayerData(bodyPart, AnimationLayerData.BODYPART, definition); + + layers.push(layer); + } + } + + if(frame.fxs && frame.fxs.length) + { + for(const fx of frame.fxs) + { + const definition = _arg_3._Str_1675(fx.action); + const layer = new AnimationLayerData(fx, AnimationLayerData.FX, definition); + + layers.push(layer); + } + } + + frames.push(layers); + + index++; + } + } + } + + public _Str_2185(k: string = null): number + { + if(!k) return this._frames.length; + + if(this._overrideFrames) + { + const _local_2 = this._overrideFrames.get(k); + + if(_local_2) return _local_2.length; + } + + return 0; + } + + public _Str_1892(): boolean + { + if(!this._overriddenActions) return false; + + return (this._overriddenActions.size > 0); + } + + public _Str_1571(): string[] + { + if(!this._overriddenActions) return null; + + const keys: string[] = []; + + for(const key of this._overriddenActions.keys()) keys.push(key); + + return keys; + } + + public _Str_707(k: string): string + { + if(!this._overriddenActions) return null; + + return this._overriddenActions.get(k); + } + + private _Str_2259(frameCount: number, _arg_2: string = null): AnimationLayerData[] + { + if(frameCount < 0) frameCount = 0; + + let layers: AnimationLayerData[] = []; + + if(!_arg_2) + { + if(this._frames.length > 0) + { + layers = this._frames[(frameCount % this._frames.length)]; + } + } + else + { + const overrideLayers = this._overrideFrames.get(_arg_2); + + if(overrideLayers && (overrideLayers.length > 0)) + { + layers = overrideLayers[(frameCount % overrideLayers.length)]; + } + } + + return layers; + } + + public _Str_1065(k: number, _arg_2: string=null): string[] + { + const _local_3: string[] = []; + + for(const layer of this._Str_2259(k, _arg_2)) + { + if(layer.type === AnimationLayerData.BODYPART) + { + _local_3.push(layer.id); + } + + else if(layer.type === AnimationLayerData.FX) + { + if(this._addData && this._addData.length) + { + for(const _local_5 of this._addData) + { + if(_local_5.id === layer.id) _local_3.push(_local_5.align); + } + } + } + } + + return _local_3; + } + + public _Str_607(frameCount: number, spriteId: string, _arg_3: string = null): AnimationLayerData + { + for(const layer of this._Str_2259(frameCount, _arg_3)) + { + if(layer.id === spriteId) return layer; + + if(layer.type === AnimationLayerData.FX) + { + if(this._addData && this._addData.length) + { + for(const addData of this._addData) + { + if(((addData.align === spriteId) && (addData.id === layer.id))) return layer; + } + } + } + } + + return null; + } + + public _Str_872(): boolean + { + return this._avatarData !== null; + } + + public _Str_776(): boolean + { + return this._directionData !== null; + } + + public _Str_706(): boolean + { + return this._addData !== null; + } + + public _Str_1550(k: string): AddDataContainer + { + if(this._addData) + { + for(const _local_2 of this._addData) + { + if(_local_2.id === k) return _local_2; + } + } + + return null; + } + + public get id(): string + { + return this._id; + } + + public get _Str_786(): SpriteDataContainer[] + { + return this._spriteData || Animation._Str_2211; + } + + public get _Str_1475(): AvatarDataContainer + { + return this._avatarData; + } + + public get _Str_1493(): DirectionDataContainer + { + return this._directionData; + } + + public get _Str_652(): string[] + { + return this._removeData || Animation._Str_2211; + } + + public get _Str_687(): AddDataContainer[] + { + return this._addData || Animation._Str_2211; + } + + public toString(): string + { + return this._description; + } + + public get resetOnToggle(): boolean + { + return this._resetOnToggle; + } +} diff --git a/src/nitro/avatar/animation/AnimationLayerData.ts b/src/nitro/avatar/animation/AnimationLayerData.ts new file mode 100644 index 00000000..5a28dcd3 --- /dev/null +++ b/src/nitro/avatar/animation/AnimationLayerData.ts @@ -0,0 +1,112 @@ +import { IAssetAnimationFramePart } from '../../../core/asset/interfaces/animation/IAssetAnimationFramePart'; +import { ActiveActionData } from '../actions/ActiveActionData'; +import { IActionDefinition } from '../actions/IActionDefinition'; +import { IActiveActionData } from '../actions/IActiveActionData'; +import { IAnimationLayerData } from './IAnimationLayerData'; + +export class AnimationLayerData implements IAnimationLayerData +{ + public static BODYPART: string = 'bodypart'; + public static FX: string = 'fx'; + + private _id: string; + private _action: IActiveActionData; + private _animationFrame: number; + private _dx: number; + private _dy: number; + private _dz: number; + private _directionOffset: number; + private _type: string; + private _base: string; + private _items: Map; + + constructor(k: IAssetAnimationFramePart, _arg_2: string, _arg_3: IActionDefinition) + { + this._id = k.id; + this._animationFrame = (k.frame || 0); + this._dx = (k.dx || 0); + this._dy = (k.dy || 0); + this._dz = (k.dz || 0); + this._directionOffset = (k.dd || 0); + this._type = _arg_2; + this._base = (k.base || ''); + this._items = new Map(); + + if(k.items) for(const _local_4 of k.items) this._items.set(_local_4.id, _local_4.base); + + let _local_5 = ''; + + if(this._base !== '') _local_5 = this._Str_2108().toString(); + + if(_arg_3) + { + this._action = new ActiveActionData(_arg_3.state, this.base); + this._action._Str_742 = _arg_3; + } + } + + public get items(): Map + { + return this._items; + } + + private _Str_2108(): number + { + let k = 0; + let index = 0; + + while(index < this._base.length) + { + k = (k + this._base.charCodeAt(index)); + + index++; + } + + return k; + } + + public get id(): string + { + return this._id; + } + + public get _Str_891(): number + { + return this._animationFrame; + } + + public get dx(): number + { + return this._dx; + } + + public get dy(): number + { + return this._dy; + } + + public get dz(): number + { + return this._dz; + } + + public get dd(): number + { + return this._directionOffset; + } + + public get type(): string + { + return this._type; + } + + public get base(): string + { + return this._base; + } + + public get action(): IActiveActionData + { + return this._action; + } +} diff --git a/src/nitro/avatar/animation/AnimationManager.ts b/src/nitro/avatar/animation/AnimationManager.ts new file mode 100644 index 00000000..f1204c3a --- /dev/null +++ b/src/nitro/avatar/animation/AnimationManager.ts @@ -0,0 +1,50 @@ +import { IAssetAnimation } from '../../../core/asset/interfaces'; +import { AvatarStructure } from '../AvatarStructure'; +import { Animation } from './Animation'; +import { IAnimation } from './IAnimation'; +import { IAnimationLayerData } from './IAnimationLayerData'; +import { IAnimationManager } from './IAnimationManager'; + +export class AnimationManager implements IAnimationManager +{ + private _animations: Map; + + constructor() + { + this._animations = new Map(); + } + + public _Str_2061(structure: AvatarStructure, _arg_2: { [index: string]: IAssetAnimation }): boolean + { + const animationData = _arg_2[Object.keys(_arg_2)[0]]; + + const animation = new Animation(structure, animationData); + + this._animations.set(animationData.name, animation); + + return true; + } + + public _Str_720(animation: string): Animation + { + const existing = this._animations.get(animation); + + if(!existing) return null; + + return existing; + } + + public _Str_607(animation: string, frameCount: number, spriteId: string): IAnimationLayerData + { + const existing = this._Str_720(animation); + + if(!existing) return null; + + return existing._Str_607(frameCount, spriteId); + } + + public get animations(): Map + { + return this._animations; + } +} diff --git a/src/nitro/avatar/animation/AvatarDataContainer.ts b/src/nitro/avatar/animation/AvatarDataContainer.ts new file mode 100644 index 00000000..466b033a --- /dev/null +++ b/src/nitro/avatar/animation/AvatarDataContainer.ts @@ -0,0 +1,137 @@ +import { AdjustmentFilter } from '@pixi/filter-adjustment'; +import { IAssetAnimationAvatar } from '../../../core/asset/interfaces'; +import { IAvatarDataContainer } from './IAvatarDataContainer'; + +export class AvatarDataContainer implements IAvatarDataContainer +{ + private _ink: number; + private _foreGround: number; + private _backGround: number; + private _colorTransform: AdjustmentFilter; + private _rgb: number; + private _r: number; + private _g: number; + private _b: number; + private _redMultiplier: number; + private _greenMultiplier: number; + private _blueMultiplier: number; + private _alphaMultiplier: number; + private _colorMap: Map; + private _paletteIsGrayscale: boolean; + + constructor(k: IAssetAnimationAvatar) + { + this._ink = k.ink; + + let foreground = k.foreground; + let background = k.background; + + foreground = foreground.replace('#', ''); + background = background.replace('#', ''); + + this._foreGround = parseInt(foreground, 16); + this._backGround = parseInt(background, 16); + this._colorTransform = null; + this._rgb = parseInt(foreground, 16); + this._r = ((this._rgb >> 16) & 0xFF); + this._g = ((this._rgb >> 8) & 0xFF); + this._b = ((this._rgb >> 0) & 0xFF); + this._redMultiplier = ((this._r / 0xFF) * 1); + this._greenMultiplier = ((this._g / 0xFF) * 1); + this._blueMultiplier = ((this._b / 0xFF) * 1); + this._alphaMultiplier = 1; + this._paletteIsGrayscale = true; + + if(this._ink === 37) + { + this._alphaMultiplier = 0.5; + this._paletteIsGrayscale = false; + } + + this._colorMap = this._Str_1181(this._backGround, this._foreGround); + } + + public get ink(): number + { + return this._ink; + } + + public get colorTransform(): AdjustmentFilter + { + return this._colorTransform; + } + + public get reds(): number[] + { + return this._colorMap.get('reds'); + } + + public get greens(): number[] + { + return this._colorMap.get('greens'); + } + + public get blues(): number[] + { + return this._colorMap.get('blues'); + } + + public get alphas(): number[] + { + return this._colorMap.get('alphas'); + } + + public get _Str_832(): boolean + { + return this._paletteIsGrayscale; + } + + private _Str_1181(k: number, _arg_2: number): Map + { + const _local_3 = ((k >> 24) & 0xFF); + const _local_4 = ((k >> 16) & 0xFF); + const _local_5 = ((k >> 8) & 0xFF); + const _local_6 = ((k >> 0) & 0xFF); + const _local_7 = ((_arg_2 >> 24) & 0xFF); + const _local_8 = ((_arg_2 >> 16) & 0xFF); + const _local_9 = ((_arg_2 >> 8) & 0xFF); + const _local_10 = ((_arg_2 >> 0) & 0xFF); + const _local_11 = ((_local_7 - _local_3) / 0xFF); + const _local_12 = ((_local_8 - _local_4) / 0xFF); + const _local_13 = ((_local_9 - _local_5) / 0xFF); + const _local_14 = ((_local_10 - _local_6) / 0xFF); + const _local_15: Map = new Map(); + const _local_16: number[] = []; + const _local_17: number[] = []; + const _local_18: number[] = []; + const _local_19: number[] = []; + let _local_20 = _local_3; + let _local_21 = _local_4; + let _local_22 = _local_5; + let _local_23 = _local_6; + let _local_24 = 0; + while(_local_24 < 0x0100) + { + if((((_local_21 == _local_4) && (_local_22 == _local_5)) && (_local_23 == _local_6))) + { + _local_20 = 0; + } + _local_20 = (_local_20 + _local_11); + _local_21 = (_local_21 + _local_12); + _local_22 = (_local_22 + _local_13); + _local_23 = (_local_23 + _local_14); + _local_19.push((_local_20 << 24)); + _local_16.push(((((_local_20 << 24) | (_local_21 << 16)) | (_local_22 << 8)) | _local_23)); + _local_17.push(((((_local_20 << 24) | (_local_21 << 16)) | (_local_22 << 8)) | _local_23)); + _local_18.push(((((_local_20 << 24) | (_local_21 << 16)) | (_local_22 << 8)) | _local_23)); + _local_24++; + } + + _local_15.set('alphas', _local_16); + _local_15.set('reds', _local_16); + _local_15.set('greens', _local_17); + _local_15.set('blues', _local_18); + + return _local_15; + } +} diff --git a/src/nitro/avatar/animation/DirectionDataContainer.ts b/src/nitro/avatar/animation/DirectionDataContainer.ts new file mode 100644 index 00000000..d9ae4627 --- /dev/null +++ b/src/nitro/avatar/animation/DirectionDataContainer.ts @@ -0,0 +1,16 @@ +import { IAssetAnimationDirection } from '../../../core/asset/interfaces'; + +export class DirectionDataContainer +{ + private _offset: number; + + constructor(k: IAssetAnimationDirection) + { + this._offset = k.offset; + } + + public get offset(): number + { + return this._offset; + } +} diff --git a/src/nitro/avatar/animation/IAnimation.ts b/src/nitro/avatar/animation/IAnimation.ts new file mode 100644 index 00000000..9cadcf60 --- /dev/null +++ b/src/nitro/avatar/animation/IAnimation.ts @@ -0,0 +1,11 @@ +export interface IAnimation +{ + _Str_872(): boolean; + _Str_776(): boolean; + _Str_706(): boolean; + id: string; + _Str_786: any; + _Str_652: any; + _Str_687: any; + resetOnToggle: boolean; +} \ No newline at end of file diff --git a/src/nitro/avatar/animation/IAnimationLayerData.ts b/src/nitro/avatar/animation/IAnimationLayerData.ts new file mode 100644 index 00000000..4c5b8449 --- /dev/null +++ b/src/nitro/avatar/animation/IAnimationLayerData.ts @@ -0,0 +1,12 @@ +import { IActiveActionData } from '../actions/IActiveActionData'; + +export interface IAnimationLayerData +{ + id: string; + action: IActiveActionData; + _Str_891: number; + dx: number; + dy: number; + dz: number; + dd: number; +} \ No newline at end of file diff --git a/src/nitro/avatar/animation/IAnimationManager.ts b/src/nitro/avatar/animation/IAnimationManager.ts new file mode 100644 index 00000000..31ce0d06 --- /dev/null +++ b/src/nitro/avatar/animation/IAnimationManager.ts @@ -0,0 +1,9 @@ +import { IAnimation } from './IAnimation'; +import { IAnimationLayerData } from './IAnimationLayerData'; + +export interface IAnimationManager +{ + animations: Map; + _Str_720(_arg_1: string): IAnimation; + _Str_607(_arg_1: string, _arg_2: number, _arg_3: string): IAnimationLayerData; +} \ No newline at end of file diff --git a/src/nitro/avatar/animation/IAvatarDataContainer.ts b/src/nitro/avatar/animation/IAvatarDataContainer.ts new file mode 100644 index 00000000..7cb2fbb3 --- /dev/null +++ b/src/nitro/avatar/animation/IAvatarDataContainer.ts @@ -0,0 +1,12 @@ +import { AdjustmentFilter } from '@pixi/filter-adjustment'; + +export interface IAvatarDataContainer +{ + ink: number; + colorTransform: AdjustmentFilter; + _Str_832: boolean; + reds: number[]; + greens: number[]; + blues: number[]; + alphas: number[]; +} \ No newline at end of file diff --git a/src/nitro/avatar/animation/ISpriteDataContainer.ts b/src/nitro/avatar/animation/ISpriteDataContainer.ts new file mode 100644 index 00000000..2dc43444 --- /dev/null +++ b/src/nitro/avatar/animation/ISpriteDataContainer.ts @@ -0,0 +1,14 @@ +import { IAnimation } from './IAnimation'; + +export interface ISpriteDataContainer +{ + animation: IAnimation; + id: string; + ink: number; + member: string; + _Str_949: boolean; + _Str_767: boolean; + _Str_809(_arg_1: number): number; + _Str_739(_arg_1: number): number; + _Str_839(_arg_1: number): number; +} \ No newline at end of file diff --git a/src/nitro/avatar/animation/SpriteDataContainer.ts b/src/nitro/avatar/animation/SpriteDataContainer.ts new file mode 100644 index 00000000..eece75bd --- /dev/null +++ b/src/nitro/avatar/animation/SpriteDataContainer.ts @@ -0,0 +1,96 @@ +import { IAssetAnimationSprite } from '../../../core/asset/interfaces'; +import { IAnimation } from './IAnimation'; +import { ISpriteDataContainer } from './ISpriteDataContainer'; + +export class SpriteDataContainer implements ISpriteDataContainer +{ + private _animation: IAnimation; + private _id: string; + private _ink: number; + private _member: string; + private _hasDirections: boolean; + private _hasStaticY: boolean; + private _dx: number[]; + private _dy: number[]; + private _dz: number[]; + + constructor(k: IAnimation, _arg_2: IAssetAnimationSprite) + { + this._animation = k; + this._id = _arg_2.id; + this._ink = _arg_2.ink; + this._member = _arg_2.member; + this._hasStaticY = _arg_2.staticY ? true : false; + this._hasDirections = _arg_2.directions ? true : false; + this._dx = []; + this._dy = []; + this._dz = []; + + const directions = _arg_2.directionList; + + if(directions && directions.length) + { + for(const direction of directions) + { + const id = direction.id; + + if(id === undefined) continue; + + this._dx[id] = (direction.dx || 0); + this._dy[id] = (direction.dy || 0); + this._dz[id] = (direction.dz || 0); + } + } + } + + public _Str_809(k: number): number + { + if(k < this._dx.length) return this._dx[k]; + + return 0; + } + + public _Str_739(k: number): number + { + if(k < this._dy.length) return this._dy[k]; + + return 0; + } + + public _Str_839(k: number): number + { + if(k < this._dz.length) return this._dz[k]; + + return 0; + } + + public get animation(): IAnimation + { + return this._animation; + } + + public get id(): string + { + return this._id; + } + + public get ink(): number + { + return this._ink; + } + + public get member(): string + { + return this._member; + } + + public get _Str_949(): boolean + { + return this._hasDirections; + } + + public get _Str_767(): boolean + { + return this._hasStaticY; + } +} diff --git a/src/nitro/avatar/cache/AvatarImageActionCache.ts b/src/nitro/avatar/cache/AvatarImageActionCache.ts new file mode 100644 index 00000000..28a49923 --- /dev/null +++ b/src/nitro/avatar/cache/AvatarImageActionCache.ts @@ -0,0 +1,96 @@ +import { IActiveActionData } from '../actions/IActiveActionData'; +import { AvatarImageBodyPartCache } from './AvatarImageBodyPartCache'; + +export class AvatarImageActionCache +{ + private _Str_586: Map; + private _Str_1233: IActiveActionData; + private _Str_1188: number; + private _disposed: boolean; + + constructor() + { + this._Str_586 = new Map(); + } + + public _Str_1565(k: IActiveActionData, _arg_2: number): void + { + if(!this._Str_1233) this._Str_1233 = k; + + const _local_3 = this._Str_1961(this._Str_1233); + + if(_local_3) _local_3._Str_1108(_arg_2); + + this._Str_1233 = k; + } + + public dispose(): void + { + if(!this._disposed) + { + if(!this._Str_586) return; + + this._Str_2089(0, 2147483647); + + this._Str_586.clear(); + + this._Str_586 = null; + this._disposed = true; + } + } + + public _Str_2089(k: number, _arg_2: number): void + { + if(!this._Str_586 || this._disposed) return; + + for(const [ key, cache ] of this._Str_586.entries()) + { + if(!cache) continue; + + const _local_3 = cache._Str_1815(); + + if((_arg_2 - _local_3) >= k) + { + cache.dispose(); + + this._Str_586.delete(key); + } + } + } + + public _Str_2244():IActiveActionData + { + return this._Str_1233; + } + + public setDirection(k: number): void + { + this._Str_1188 = k; + } + + public getDirection(): number + { + return this._Str_1188; + } + + public _Str_1961(k: IActiveActionData=null): AvatarImageBodyPartCache + { + if(!this._Str_1233) return null; + + if(!k) k = this._Str_1233; + + if(k._Str_707) return this._Str_586.get(k._Str_707); + + return this._Str_586.get(k.id); + } + + public _Str_1765(k: IActiveActionData, _arg_2: AvatarImageBodyPartCache): void + { + if(k._Str_707) this._Str_586.set(k._Str_707, _arg_2); + else this._Str_586.set(k.id, _arg_2); + } + + private _Str_587(k: string): void + { + } +} \ No newline at end of file diff --git a/src/nitro/avatar/cache/AvatarImageBodyPartCache.ts b/src/nitro/avatar/cache/AvatarImageBodyPartCache.ts new file mode 100644 index 00000000..dc331e8f --- /dev/null +++ b/src/nitro/avatar/cache/AvatarImageBodyPartCache.ts @@ -0,0 +1,57 @@ +import { Nitro } from '../../Nitro'; +import { AvatarImageDirectionCache } from './AvatarImageDirectionCache'; + +export class AvatarImageBodyPartCache +{ + private _Str_586: Map; + private _Str_1509: number; + + constructor() + { + this._Str_586 = new Map(); + + this._Str_1108(Nitro.instance.time); + } + + public dispose(): void + { + this._Str_587('[dispose]'); + + if(!this._Str_586) return; + + for(const direction of this._Str_586.values()) + { + if(direction) direction.dispose(); + } + + this._Str_586.clear(); + } + + public _Str_2070(k: number): AvatarImageDirectionCache + { + const existing = this._Str_586.get(k.toString()); + + if(!existing) return null; + + return existing; + } + + public _Str_2168(k: number, _arg_2: AvatarImageDirectionCache): void + { + this._Str_586.set(k.toString(), _arg_2); + } + + public _Str_1108(k: number): void + { + this._Str_1509 = k; + } + + public _Str_1815(): number + { + return this._Str_1509; + } + + private _Str_587(k: string): void + { + } +} diff --git a/src/nitro/avatar/cache/AvatarImageCache.ts b/src/nitro/avatar/cache/AvatarImageCache.ts new file mode 100644 index 00000000..9c2bb85a --- /dev/null +++ b/src/nitro/avatar/cache/AvatarImageCache.ts @@ -0,0 +1,527 @@ +import { Container, Matrix, Point, Rectangle, Sprite, Texture } from 'pixi.js'; +import { RoomObjectSpriteData } from '../../../room/data/RoomObjectSpriteData'; +import { Nitro } from '../../Nitro'; +import { IActiveActionData } from '../actions/IActiveActionData'; +import { AssetAliasCollection } from '../alias/AssetAliasCollection'; +import { AnimationLayerData } from '../animation/AnimationLayerData'; +import { AvatarImageBodyPartContainer } from '../AvatarImageBodyPartContainer'; +import { AvatarImagePartContainer } from '../AvatarImagePartContainer'; +import { AvatarStructure } from '../AvatarStructure'; +import { AvatarDirectionAngle } from '../enum/AvatarDirectionAngle'; +import { AvatarFigurePartType } from '../enum/AvatarFigurePartType'; +import { AvatarScaleType } from '../enum/AvatarScaleType'; +import { GeometryType } from '../enum/GeometryType'; +import { IAvatarImage } from '../IAvatarImage'; +import { AvatarCanvas } from '../structure/AvatarCanvas'; +import { AvatarImageActionCache } from './AvatarImageActionCache'; +import { AvatarImageBodyPartCache } from './AvatarImageBodyPartCache'; +import { AvatarImageDirectionCache } from './AvatarImageDirectionCache'; +import { ImageData } from './ImageData'; + +export class AvatarImageCache +{ + private static _Str_2189: number = 60000; + + private _structure: AvatarStructure; + private _avatar: IAvatarImage; + private _assets: AssetAliasCollection; + private _scale: string; + private _cache: Map; + private _canvas: AvatarCanvas; + private _disposed: boolean; + private _geometryType: string; + private _unionImages: ImageData[]; + private _matrix: Matrix; + private _serverRenderData: RoomObjectSpriteData[]; + + constructor(k: AvatarStructure, _arg_2: IAvatarImage, _arg_3: AssetAliasCollection, _arg_4: string) + { + this._structure = k; + this._avatar = _arg_2; + this._assets = _arg_3; + this._scale = _arg_4; + this._cache = new Map(); + this._canvas = null; + this._disposed = false; + this._unionImages = []; + this._matrix = new Matrix(); + this._serverRenderData = []; + } + + public dispose(): void + { + if(this._disposed) return; + + this._structure = null; + this._avatar = null; + this._assets = null; + this._canvas = null; + this._disposed = true; + + if(this._cache) + { + for(const cache of this._cache.values()) + { + if(!cache) continue; + + cache.dispose(); + } + + this._cache = null; + } + + if(this._unionImages) + { + for(const image of this._unionImages) + { + if(!image) continue; + + image.dispose(); + } + + this._unionImages = []; + } + } + + public _Str_1086(k: number = 60000): void + { + const time = Nitro.instance.time; + + if(this._cache) + { + for(const cache of this._cache.values()) + { + if(!cache) continue; + + cache._Str_2089(k, time); + } + } + } + + public _Str_741(k: IActiveActionData): void + { + if(this._cache) + { + for(const cache of this._cache.values()) + { + if(!cache) continue; + + cache._Str_1565(k, 0); + } + } + } + + public setDirection(k: string, _arg_2: number): void + { + const parts = this._structure._Str_1695(k); + + if(parts) + { + for(const part of parts) + { + const actionCache = this._Str_1050(part); + + if(!actionCache) continue; + + actionCache.setDirection(_arg_2); + } + } + } + + public _Str_1565(k: IActiveActionData, _arg_2: number): void + { + const _local_3 = this._structure._Str_2021(k, this._avatar); + + for(const _local_4 of _local_3) + { + const _local_5 = this._Str_1050(_local_4); + + if(_local_5) _local_5._Str_1565(k, _arg_2); + } + } + + public _Str_2014(k: string): void + { + if(this._geometryType === k) return; + + if((((this._geometryType === GeometryType.SITTING) && (k === GeometryType.VERTICAL)) || ((this._geometryType === GeometryType.VERTICAL) && (k === GeometryType.SITTING)) || ((this._geometryType === GeometryType.SNOWWARS_HORIZONTAL) && (k = GeometryType.SNOWWARS_HORIZONTAL)))) + { + this._geometryType = k; + this._canvas = null; + + return; + } + + this._Str_1086(0); + + this._geometryType = k; + this._canvas = null; + } + + public _Str_1629(k: string, frameNumber: number, _arg_3: boolean = false): AvatarImageBodyPartContainer + { + let _local_4 = this._Str_1050(k); + + if(!_local_4) + { + _local_4 = new AvatarImageActionCache(); + + this._cache.set(k, _local_4); + } + + let _local_5 = _local_4.getDirection(); + let _local_7 = _local_4._Str_2244(); + let frameCount = frameNumber; + + if(_local_7._Str_742._Str_812) frameCount -= _local_7._Str_664; + + let _local_8 = _local_7; + let _local_9: string[] = []; + let _local_10: Map = new Map(); + const _local_11 = new Point(); + + if(!((!(_local_7)) || (!(_local_7._Str_742)))) + { + if(_local_7._Str_742._Str_861) + { + let _local_15 = _local_5; + + const _local_16 = this._structure._Str_720(((_local_7._Str_742.state + '.') + _local_7._Str_727)); + const _local_17 = (frameNumber - _local_7._Str_664); + + if(_local_16) + { + const _local_18 = _local_16._Str_607(_local_17, k, _local_7._Str_707); + + if(_local_18) + { + _local_15 = (_local_5 + _local_18.dd); + + if(_local_18.dd < 0) + { + if(_local_15 < 0) + { + _local_15 = (8 + _local_15); + } + else if(_local_15 > 7) _local_15 = (8 - _local_15); + } + else + { + if(_local_15 < 0) + { + _local_15 = (_local_15 + 8); + } + else if(_local_15 > 7) _local_15 = (_local_15 - 8); + } + + if(this._scale === AvatarScaleType.LARGE) + { + _local_11.x = _local_18.dx; + _local_11.y = _local_18.dy; + } + else + { + _local_11.x = (_local_18.dx / 2); + _local_11.y = (_local_18.dy / 2); + } + + frameCount = _local_18._Str_891; + + if(_local_18.action) + { + _local_7 = _local_18.action; + } + + if(_local_18.type === AnimationLayerData.BODYPART) + { + if(_local_18.action != null) + { + _local_8 = _local_18.action; + } + + _local_5 = _local_15; + } + else if(_local_18.type === AnimationLayerData.FX) _local_5 = _local_15; + + _local_10 = _local_18.items; + } + + _local_9 = _local_16._Str_652; + } + } + } + + let _local_12 = _local_4._Str_1961(_local_8); + + if(!_local_12 || _arg_3) + { + _local_12 = new AvatarImageBodyPartCache(); + _local_4._Str_1765(_local_8, _local_12); + } + + let _local_13 = _local_12._Str_2070(_local_5); + + if(!_local_13 || _arg_3) + { + const _local_19 = this._structure._Str_713(k, this._avatar.getFigure(), _local_8, this._geometryType, _local_5, _local_9, this._avatar, _local_10); + + _local_13 = new AvatarImageDirectionCache(_local_19); + + _local_12._Str_2168(_local_5, _local_13); + } + + let _local_14 = _local_13._Str_1629(frameCount); + + if(!_local_14 || _arg_3) + { + const _local_20 = _local_13._Str_1699(); + + _local_14 = this._Str_1834(_local_5, _local_20, frameCount, _local_7, _arg_3); + + if(_local_14 && !_arg_3) + { + if(_local_14._Str_1807) _local_13._Str_1924(_local_14, frameCount); + } + else + { + return null; + } + } + + const offset = this._structure._Str_1888(_local_8, _local_5, frameCount, k); + + _local_11.x += offset.x; + _local_11.y += offset.y; + + _local_14.offset = _local_11; + + return _local_14; + } + + public _Str_1009(): any[] + { + this._serverRenderData = []; + + return this._serverRenderData; + } + + public _Str_1050(k: string): AvatarImageActionCache + { + let existing = this._cache.get(k); + + if(!existing) + { + existing = new AvatarImageActionCache(); + + this._cache.set(k, existing); + } + + return existing; + } + + private _Str_1834(direction: number, containers: AvatarImagePartContainer[], frameCount: number, _arg_4: IActiveActionData, renderServerData: boolean = false): AvatarImageBodyPartContainer + { + if(!containers || !containers.length) return null; + + if(!this._canvas) + { + this._canvas = this._structure._Str_1664(this._scale, this._geometryType); + + if(!this._canvas) return null; + } + + const isFlipped = AvatarDirectionAngle.DIRECTION_IS_FLIPPED[direction] || false; + let assetPartDefinition = _arg_4._Str_742._Str_778; + let isCacheable = true; + let containerIndex = (containers.length - 1); + + while(containerIndex >= 0) + { + const container = containers[containerIndex]; + + let color = 16777215; + + if(!((direction == 7) && ((container._Str_1669 === 'fc') || (container._Str_1669 === 'ey')))) + { + if(!((container._Str_1669 === 'ri') && !container._Str_1502)) + { + const partId = container._Str_1502; + const animationFrame = container._Str_2258(frameCount); + + let partType = container._Str_1669; + let frameNumber = 0; + + if(animationFrame) + { + frameNumber = animationFrame.number; + + if((animationFrame._Str_778) && (animationFrame._Str_778 !== '')) assetPartDefinition = animationFrame._Str_778; + } + else frameNumber = container._Str_1674(frameCount); + + let assetDirection = direction; + let flipH = false; + + if(isFlipped) + { + if(((assetPartDefinition === 'wav') && (((partType === AvatarFigurePartType.LEFT_HAND) || (partType === AvatarFigurePartType.LEFT_SLEEVE)) || (partType === AvatarFigurePartType.LEFT_COAT_SLEEVE))) || ((assetPartDefinition === 'drk') && (((partType === AvatarFigurePartType.RIGHT_HAND) || (partType === AvatarFigurePartType.RIGHT_SLEEVE)) || (partType === AvatarFigurePartType.RIGHT_COAT_SLEEVE))) || ((assetPartDefinition === 'blw') && (partType === AvatarFigurePartType.RIGHT_HAND)) || ((assetPartDefinition === 'sig') && (partType === AvatarFigurePartType.LEFT_HAND)) || ((assetPartDefinition === 'respect') && (partType === AvatarFigurePartType.LEFT_HAND)) || (partType === AvatarFigurePartType.RIGHT_HAND_ITEM) || (partType === AvatarFigurePartType.LEFT_HAND_ITEM) || (partType === AvatarFigurePartType.CHEST_PRINT)) + { + flipH = true; + } + else + { + if(direction === 4) assetDirection = 2; + else if(direction === 5) assetDirection = 1; + else if(direction === 6) assetDirection = 0; + + if(container._Str_1666 !== partType) partType = container._Str_1666; + } + } + + let assetName = (this._scale + '_' + assetPartDefinition + '_' + partType + '_' + partId + '_' + assetDirection + '_' + frameNumber); + let asset = this._assets.getAsset(assetName); + + if(!asset) + { + assetName = (this._scale + '_std_' + partType + '_' + partId + '_' + assetDirection + '_0'); + asset = this._assets.getAsset(assetName); + } + + if(asset) + { + const texture = asset.texture; + + if(!texture || !texture.valid || !texture.baseTexture) + { + isCacheable = false; + } + else + { + if(container.isColorable && container.color) color = container.color._Str_915; + + const offset = new Point(-(asset.x), -(asset.y)); + + if(flipH) offset.x = (offset.x + ((this._scale === AvatarScaleType.LARGE) ? 65 : 31)); + + if(renderServerData) + { + const spriteData = new RoomObjectSpriteData(); + + spriteData.name = this._assets._Str_2125(assetName); + spriteData.x = (-(offset.x) - 33); + spriteData.y = -(offset.y); + spriteData.z = (this._serverRenderData.length * -0.0001); + spriteData.width = asset.rectangle.width; + spriteData.height = asset.rectangle.height; + spriteData.flipH = flipH; + + if(assetPartDefinition === 'lay') spriteData.x = (spriteData.x + 53); + + if(isFlipped) + { + spriteData.flipH = (!(spriteData.flipH)); + + if(spriteData.flipH) spriteData.x = (-(spriteData.x) - texture.width); + else spriteData.x = (spriteData.x + 65); + } + + if(container.isColorable) spriteData.color = `${ color }`; + + this._serverRenderData.push(spriteData); + } + + this._unionImages.push(new ImageData(texture, asset.rectangle, offset, flipH, color)); + } + } + } + } + + containerIndex--; + } + + if(!this._unionImages.length) return null; + + const imageData = this._Str_1236(this._unionImages, isFlipped); + const canvasOffset = ((this._scale === AvatarScaleType.LARGE) ? (this._canvas.height - 16) : (this._canvas.height - 8)); + const offset = new Point(-(imageData._Str_1076.x), (canvasOffset - imageData._Str_1076.y)); + + if(isFlipped && (assetPartDefinition !== 'lay')) offset.x = (offset.x + ((this._scale === AvatarScaleType.LARGE) ? 67 : 31)); + + let imageIndex = (this._unionImages.length - 1); + + while(imageIndex >= 0) + { + const _local_17 = this._unionImages.pop(); + + if(_local_17) _local_17.dispose(); + + imageIndex--; + } + + return new AvatarImageBodyPartContainer(imageData.container, offset, isCacheable); + } + + private _Str_1652(k: number): string + { + let _local_2: string = (k * 0xFF).toString(16); + if(_local_2.length < 2) + { + _local_2 = ('0' + _local_2); + } + return _local_2; + } + + private _Str_1236(k: ImageData[], isFlipped: boolean): ImageData + { + const bounds = new Rectangle(); + + for(const data of k) data && bounds.enlarge(data._Str_1567); + + const point = new Point(-(bounds.x), -(bounds.y)); + const container = new Container(); + + const sprite = new Sprite(Texture.EMPTY); + + sprite.width = bounds.width; + sprite.height = bounds.height; + + container.addChild(sprite); + + for(const data of k) + { + if(!data) continue; + + const texture = data.texture; + const color = data.color; + const flipH = (!(isFlipped && data.flipH) && (isFlipped || data.flipH)); + const regPoint = point.clone(); + + regPoint.x -= data._Str_1076.x; + regPoint.y -= data._Str_1076.y; + + if(isFlipped) regPoint.x = (container.width - (regPoint.x + data.rect.width)); + + if(flipH) + { + this._matrix.a = -1; + this._matrix.tx = ((data.rect.x + data.rect.width) + regPoint.x); + this._matrix.ty = (regPoint.y - data.rect.y); + } + else + { + this._matrix.a = 1; + this._matrix.tx = (regPoint.x - data.rect.x); + this._matrix.ty = (regPoint.y - data.rect.y); + } + + const sprite = new Sprite(texture); + + sprite.tint = color; + sprite.transform.setFromMatrix(this._matrix); + + container.addChild(sprite); + } + + return new ImageData(null, container.getLocalBounds(), point, isFlipped, null, container); + } +} diff --git a/src/nitro/avatar/cache/AvatarImageDirectionCache.ts b/src/nitro/avatar/cache/AvatarImageDirectionCache.ts new file mode 100644 index 00000000..c78d56aa --- /dev/null +++ b/src/nitro/avatar/cache/AvatarImageDirectionCache.ts @@ -0,0 +1,59 @@ +import { AvatarImageBodyPartContainer } from '../AvatarImageBodyPartContainer'; +import { AvatarImagePartContainer } from '../AvatarImagePartContainer'; + +export class AvatarImageDirectionCache +{ + private _partList: AvatarImagePartContainer[]; + private _images: Map; + + constructor(k: AvatarImagePartContainer[]) + { + this._partList = k; + this._images = new Map(); + } + + public dispose(): void + { + for(const image of this._images.values()) image && image.dispose(); + + this._images = null; + } + + public _Str_1699(): AvatarImagePartContainer[] + { + return this._partList; + } + + public _Str_1629(k: number): AvatarImageBodyPartContainer + { + const existing = this._images.get(this._Str_2219(k)); + + if(!existing) return null; + + return existing; + } + + public _Str_1924(k: AvatarImageBodyPartContainer, _arg_2: number): void + { + const name = this._Str_2219(_arg_2); + + const existing = this._images.get(name); + + if(existing) existing.dispose(); + + this._images.set(name, k); + } + + private _Str_2219(k: number): string + { + let name = ''; + + for(const part of this._partList) name += (part._Str_1206(k) + '/'); + + return name; + } + + private _Str_587(k: string): void + { + } +} \ No newline at end of file diff --git a/src/nitro/avatar/cache/ImageData.ts b/src/nitro/avatar/cache/ImageData.ts new file mode 100644 index 00000000..6f478d5b --- /dev/null +++ b/src/nitro/avatar/cache/ImageData.ts @@ -0,0 +1,65 @@ +import { Container, Point, Rectangle, Texture } from 'pixi.js'; + +export class ImageData +{ + private _texture: Texture; + private _container: Container; + private _rect: Rectangle; + private _regPoint: Point; + private _flipH: boolean; + private _color: number; + + constructor(texture: Texture, rectangle: Rectangle, _arg_3: Point, flipH: boolean, color: number, container: Container = null) + { + this._texture = texture; + this._container = container; + this._rect = rectangle; + this._regPoint = _arg_3; + this._flipH = flipH; + this._color = color; + + if(flipH) this._regPoint.x = (-(this._regPoint.x) + rectangle.width); + } + + public dispose(): void + { + this._texture = null; + this._regPoint = null; + this._color = null; + } + + public get texture(): Texture + { + return this._texture; + } + + public get container(): Container + { + return this._container; + } + + public get rect(): Rectangle + { + return this._rect; + } + + public get _Str_1076(): Point + { + return this._regPoint; + } + + public get flipH(): boolean + { + return this._flipH; + } + + public get color(): number + { + return this._color; + } + + public get _Str_1567(): Rectangle + { + return new Rectangle(-(this._regPoint.x), -(this._regPoint.y), this._rect.width, this._rect.height); + } +} \ No newline at end of file diff --git a/src/nitro/avatar/data/HabboAvatarAnimations.json b/src/nitro/avatar/data/HabboAvatarAnimations.json new file mode 100644 index 00000000..d6f6ca59 --- /dev/null +++ b/src/nitro/avatar/data/HabboAvatarAnimations.json @@ -0,0 +1,827 @@ +{ + "animations": [ + { + "id": "Move", + "parts": [ + { + "setType": "bd", + "frames": [ + { + "number": 0, + "assetPartDefinition": "wlk" + }, + { + "number": 1, + "assetPartDefinition": "wlk" + }, + { + "number": 2, + "assetPartDefinition": "wlk" + }, + { + "number": 3, + "assetPartDefinition": "wlk" + } + ] + }, + { + "setType": "bds", + "frames": [ + { + "number": 0, + "assetPartDefinition": "wlk" + }, + { + "number": 1, + "assetPartDefinition": "wlk" + }, + { + "number": 2, + "assetPartDefinition": "wlk" + }, + { + "number": 3, + "assetPartDefinition": "wlk" + } + ] + }, + { + "setType": "ss", + "frames": [ + { + "number": 0, + "assetPartDefinition": "wlk" + }, + { + "number": 1, + "assetPartDefinition": "wlk" + }, + { + "number": 2, + "assetPartDefinition": "wlk" + }, + { + "number": 3, + "assetPartDefinition": "wlk" + } + ] + }, + { + "setType": "lg", + "frames": [ + { + "number": 0, + "assetPartDefinition": "wlk" + }, + { + "number": 1, + "assetPartDefinition": "wlk" + }, + { + "number": 2, + "assetPartDefinition": "wlk" + }, + { + "number": 3, + "assetPartDefinition": "wlk" + } + ] + }, + { + "setType": "sh", + "frames": [ + { + "number": 0, + "assetPartDefinition": "wlk" + }, + { + "number": 1, + "assetPartDefinition": "wlk" + }, + { + "number": 2, + "assetPartDefinition": "wlk" + }, + { + "number": 3, + "assetPartDefinition": "wlk" + } + ] + }, + { + "setType": "lh", + "frames": [ + { + "number": 0, + "assetPartDefinition": "wlk" + }, + { + "number": 1, + "assetPartDefinition": "wlk" + }, + { + "number": 2, + "assetPartDefinition": "wlk" + }, + { + "number": 3, + "assetPartDefinition": "wlk" + } + ] + }, + { + "setType": "lhs", + "frames": [ + { + "number": 0, + "assetPartDefinition": "wlk" + }, + { + "number": 1, + "assetPartDefinition": "wlk" + }, + { + "number": 2, + "assetPartDefinition": "wlk" + }, + { + "number": 3, + "assetPartDefinition": "wlk" + } + ] + }, + { + "setType": "ls", + "frames": [ + { + "number": 0, + "assetPartDefinition": "wlk" + }, + { + "number": 1, + "assetPartDefinition": "wlk" + }, + { + "number": 2, + "assetPartDefinition": "wlk" + }, + { + "number": 3, + "assetPartDefinition": "wlk" + } + ] + }, + { + "setType": "lc", + "frames": [ + { + "number": 0, + "assetPartDefinition": "wlk" + }, + { + "number": 1, + "assetPartDefinition": "wlk" + }, + { + "number": 2, + "assetPartDefinition": "wlk" + }, + { + "number": 3, + "assetPartDefinition": "wlk" + } + ] + }, + { + "setType": "rh", + "frames": [ + { + "number": 0, + "assetPartDefinition": "wlk" + }, + { + "number": 1, + "assetPartDefinition": "wlk" + }, + { + "number": 2, + "assetPartDefinition": "wlk" + }, + { + "number": 3, + "assetPartDefinition": "wlk" + } + ] + }, + { + "setType": "rhs", + "frames": [ + { + "number": 0, + "assetPartDefinition": "wlk" + }, + { + "number": 1, + "assetPartDefinition": "wlk" + }, + { + "number": 2, + "assetPartDefinition": "wlk" + }, + { + "number": 3, + "assetPartDefinition": "wlk" + } + ] + }, + { + "setType": "rs", + "frames": [ + { + "number": 0, + "assetPartDefinition": "wlk" + }, + { + "number": 1, + "assetPartDefinition": "wlk" + }, + { + "number": 2, + "assetPartDefinition": "wlk" + }, + { + "number": 3, + "assetPartDefinition": "wlk" + } + ] + }, + { + "setType": "rc", + "frames": [ + { + "number": 0, + "assetPartDefinition": "wlk" + }, + { + "number": 1, + "assetPartDefinition": "wlk" + }, + { + "number": 2, + "assetPartDefinition": "wlk" + }, + { + "number": 3, + "assetPartDefinition": "wlk" + } + ] + }, + { + "setType": "ch", + "frames": [ + { + "number": 0, + "assetPartDefinition": "wlk" + }, + { + "number": 1, + "assetPartDefinition": "wlk" + }, + { + "number": 2, + "assetPartDefinition": "wlk" + }, + { + "number": 3, + "assetPartDefinition": "wlk" + } + ] + } + ] + }, + { + "id": "Wave", + "parts": [ + { + "setType": "lh", + "frames": [ + { + "number": 0, + "assetPartDefinition": "wav" + }, + { + "number": 1, + "assetPartDefinition": "wav" + } + ] + }, + { + "setType": "lhs", + "frames": [ + { + "number": 0, + "assetPartDefinition": "wav" + }, + { + "number": 1, + "assetPartDefinition": "wav" + } + ] + }, + { + "setType": "ls", + "frames": [ + { + "number": 0, + "assetPartDefinition": "wav" + }, + { + "number": 1, + "assetPartDefinition": "wav" + } + ] + }, + { + "setType": "lc", + "frames": [ + { + "number": 0, + "assetPartDefinition": "wav" + }, + { + "number": 1, + "assetPartDefinition": "wav" + } + ] + }, + { + "setType": "ch", + "frames": [ + { + "number": 0, + "assetPartDefinition": "wav" + }, + { + "number": 1, + "assetPartDefinition": "wav" + }, + { + "number": 2, + "assetPartDefinition": "wav" + }, + { + "number": 3, + "assetPartDefinition": "wav" + } + ] + } + ] + }, + { + "id": "Talk", + "parts": [ + { + "setType": "hd", + "frames": [ + { + "number": 0, + "assetPartDefinition": "spk" + }, + { + "number": 1, + "assetPartDefinition": "spk" + } + ] + }, + { + "setType": "fc", + "frames": [ + { + "number": 0, + "assetPartDefinition": "spk" + }, + { + "number": 1, + "assetPartDefinition": "spk" + } + ] + }, + { + "setType": "fa", + "frames": [ + { + "number": 0, + "assetPartDefinition": "spk" + }, + { + "number": 1, + "assetPartDefinition": "spk" + } + ] + } + ] + }, + { + "id": "Sign", + "parts": [ + { + "setType": "lh", + "frames": [ + { + "number": 0, + "assetPartDefinition": "sig" + } + ] + }, + { + "setType": "li", + "frames": [ + { + "number": 0, + "assetPartDefinition": "sig" + } + ] + }, + { + "setType": "ls", + "frames": [ + { + "number": 0, + "assetPartDefinition": "wav" + } + ] + }, + { + "setType": "lc", + "frames": [ + { + "number": 0, + "assetPartDefinition": "wav" + } + ] + } + ] + }, + { + "id": "Respect", + "parts": [ + { + "setType": "lh", + "frames": [ + { + "number": 0, + "assetPartDefinition": "respect", + "repeats": 15 + }, + { + "number": 1, + "assetPartDefinition": "respect", + "repeats": 15 + } + ] + }, + { + "setType": "ls", + "frames": [ + { + "number": 0, + "assetPartDefinition": "wav", + "repeats": 15 + }, + { + "number": 1, + "assetPartDefinition": "wav", + "repeats": 15 + } + ] + }, + { + "setType": "lc", + "frames": [ + { + "number": 0, + "assetPartDefinition": "wav", + "repeats": 15 + }, + { + "number": 1, + "assetPartDefinition": "wav", + "repeats": 15 + } + ] + } + ] + }, + { + "id": "Blow", + "parts": [ + { + "setType": "rh", + "frames": [ + { + "number": 0, + "assetPartDefinition": "blw", + "repeats": 10 + }, + { + "number": 1, + "assetPartDefinition": "blw", + "repeats": 10 + } + ] + }, + { + "setType": "rs", + "frames": [ + { + "number": 0, + "assetPartDefinition": "drk" + } + ] + }, + { + "setType": "rc", + "frames": [ + { + "number": 0, + "assetPartDefinition": "drk" + } + ] + }, + { + "setType": "ri", + "frames": [ + { + "number": 0, + "assetPartDefinition": "" + } + ] + }, + { + "setType": "ey", + "frames": [ + { + "number": 0, + "assetPartDefinition": "std", + "repeats": 10 + }, + { + "number": 0, + "assetPartDefinition": "eyb", + "repeats": 10 + } + ] + }, + { + "setType": "fc", + "frames": [ + { + "number": 0, + "assetPartDefinition": "std", + "repeats": 10 + }, + { + "number": 0, + "assetPartDefinition": "blw", + "repeats": 10 + } + ] + } + ] + }, + { + "id": "Laugh", + "parts": [ + { + "setType": "rh", + "frames": [ + { + "number": 0, + "assetPartDefinition": "blw" + } + ] + }, + { + "setType": "rs", + "frames": [ + { + "number": 0, + "assetPartDefinition": "drk" + } + ] + }, + { + "setType": "rc", + "frames": [ + { + "number": 0, + "assetPartDefinition": "drk" + } + ] + }, + { + "setType": "ri", + "frames": [ + { + "number": 0, + "assetPartDefinition": "" + } + ] + }, + { + "setType": "ey", + "frames": [ + { + "number": 0, + "assetPartDefinition": "std", + "repeats": 2 + } + ] + }, + { + "setType": "fc", + "frames": [ + { + "number": 0, + "assetPartDefinition": "sml" + } + ] + } + ], + "offsets": { + "frames": [ + { + "id": 0, + "directions": [ + { + "id": 0, + "bodyParts": [ + { + "id": "head", + "dx": 0, + "dy": 1 + } + ] + }, + { + "id": 1, + "bodyParts": [ + { + "id": "head", + "dx": 0, + "dy": 1 + } + ] + }, + { + "id": 2, + "bodyParts": [ + { + "id": "head", + "dx": 0, + "dy": 1 + } + ] + }, + { + "id": 3, + "bodyParts": [ + { + "id": "head", + "dx": 0, + "dy": 1 + } + ] + }, + { + "id": 4, + "bodyParts": [ + { + "id": "head", + "dx": 0, + "dy": 1 + } + ] + }, + { + "id": 5, + "bodyParts": [ + { + "id": "head", + "dx": 0, + "dy": 1 + } + ] + }, + { + "id": 6, + "bodyParts": [ + { + "id": "head", + "dx": 0, + "dy": 1 + } + ] + }, + { + "id": 7, + "bodyParts": [ + { + "id": "head", + "dx": 0, + "dy": 1 + } + ] + } + ] + }, + { + "id": 1, + "directions": [ + { + "id": 0, + "bodyParts": [ + { + "id": "head", + "dx": 0, + "dy": 0 + } + ] + }, + { + "id": 1, + "bodyParts": [ + { + "id": "head", + "dx": 0, + "dy": 0 + } + ] + }, + { + "id": 2, + "bodyParts": [ + { + "id": "head", + "dx": 0, + "dy": 0 + } + ] + }, + { + "id": 3, + "bodyParts": [ + { + "id": "head", + "dx": 0, + "dy": 0 + } + ] + }, + { + "id": 4, + "bodyParts": [ + { + "id": "head", + "dx": 0, + "dy": 0 + } + ] + }, + { + "id": 5, + "bodyParts": [ + { + "id": "head", + "dx": 0, + "dy": 0 + } + ] + }, + { + "id": 6, + "bodyParts": [ + { + "id": "head", + "dx": 0, + "dy": 0 + } + ] + }, + { + "id": 7, + "bodyParts": [ + { + "id": "head", + "dx": 0, + "dy": 0 + } + ] + } + ] + } + ] + } + } + ] +} \ No newline at end of file diff --git a/src/nitro/avatar/data/HabboAvatarGeometry.json b/src/nitro/avatar/data/HabboAvatarGeometry.json new file mode 100644 index 00000000..5f19f16b --- /dev/null +++ b/src/nitro/avatar/data/HabboAvatarGeometry.json @@ -0,0 +1,1830 @@ +{ + "geometry": { + "direction": 0, + "camera": { + "x": 0, + "y": 0, + "z": 10 + }, + "canvases": [ + { + "scale": "h", + "geometries": [ + { + "id": "vertical", + "width": 90, + "height": 130, + "dx": 0, + "dy": 0 + }, + { + "id": "sitting", + "width": 90, + "height": 130, + "dx": 0, + "dy": 0 + }, + { + "id": "horizontal", + "width": 128, + "height": 80, + "dx": 30, + "dy": 0 + }, + { + "id": "swhorizontal", + "width": 192, + "height": 120, + "dx": 0, + "dy": -40 + } + ] + }, + { + "scale": "sh", + "geometries": [ + { + "id": "vertical", + "width": 45, + "height": 72, + "dx": 0, + "dy": 0 + }, + { + "id": "sitting", + "width": 45, + "height": 72, + "dx": 0, + "dy": 0 + }, + { + "id": "horizontal", + "width": 64, + "height": 50, + "dx": 15, + "dy": -10 + }, + { + "id": "swhorizontal", + "width": 96, + "height": 70, + "dx": 0, + "dy": -20 + }, + { + "id": "swim", + "width": 64, + "height": 70, + "dx": 25, + "dy": 10 + } + ] + } + ], + "avatarSets": [ + { + "id": "full", + "avatarSets": [ + { + "id": "body", + "main": true, + "bodyParts": [ + { + "id": "top" + }, + { + "id": "bottom" + }, + { + "id": "behind" + }, + { + "id": "torso" + }, + { + "id": "leftitem" + }, + { + "id": "rightitem" + }, + { + "id": "leftarm" + }, + { + "id": "rightarm" + } + ] + }, + { + "id": "head", + "bodyParts": [ + { + "id": "head" + } + ] + } + ] + } + ], + "types": [ + { + "id": "vertical", + "bodyParts": [ + { + "id": "top", + "x": 0, + "y": 0, + "z": 0.0, + "radius": 2.0 + }, + { + "id": "bottom", + "x": 0, + "y": 0, + "z": 0.0, + "radius": 0.001 + }, + { + "id": "behind", + "x": 0, + "y": 0, + "z": 0.2, + "radius": 0.3 + }, + { + "id": "torso", + "x": 0, + "y": 0, + "z": 0.0, + "radius": 0.4, + "items": [ + { + "id": "bd", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.01, + "nx": 0, + "ny": 0, + "nz": -1, + "double": true + }, + { + "id": "bds", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.01, + "nx": 0, + "ny": 0, + "nz": -1, + "double": true + }, + { + "id": "ch", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.04, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "sh", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.02, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "lg", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.03, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "ss", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.04, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "cp", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.045, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "wa", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.05, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "cc", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.06, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "ca", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.07, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + } + ] + }, + { + "id": "leftitem", + "x": 0, + "y": 0, + "z": -0.29, + "radius": 0.3, + "items": [ + { + "id": "li", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.01, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + } + ] + }, + { + "id": "rightitem", + "x": 0, + "y": 0, + "z": -0.29, + "radius": 0.3, + "items": [ + { + "id": "ri", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.01, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + } + ] + }, + { + "id": "leftarm", + "x": -1, + "y": 0, + "z": -0.51, + "radius": 0.5, + "items": [ + { + "id": "lh", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.01, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "lhs", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.01, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "ls", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.02, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "lc", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.025, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + } + ] + }, + { + "id": "rightarm", + "x": 1, + "y": 0, + "z": -0.51, + "radius": 0.5, + "items": [ + { + "id": "rh", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.01, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "rhs", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.01, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "rs", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.02, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "rc", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.025, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + } + ] + }, + { + "id": "head", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.5, + "items": [ + { + "id": "hd", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.01, + "nx": 0, + "ny": 0, + "nz": -1, + "double": true + }, + { + "id": "fc", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.02, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "ey", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.03, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "hr", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.04, + "nx": 0, + "ny": 0, + "nz": -1, + "double": true + }, + { + "id": "hrb", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.05, + "nx": 0, + "ny": 0, + "nz": -1, + "double": true + }, + { + "id": "fa", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.06, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "ea", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.07, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "ha", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.08, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "he", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.09, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + } + ] + } + ] + }, + { + "id": "sitting", + "bodyParts": [ + { + "id": "top", + "x": 0, + "y": 0, + "z": 0.0, + "radius": 2.0 + }, + { + "id": "bottom", + "x": 0, + "y": 0, + "z": 0.0, + "radius": 0.001 + }, + { + "id": "behind", + "x": 0, + "y": 0, + "z": 0.2, + "radius": 0.3 + }, + { + "id": "torso", + "x": 0, + "y": 0, + "z": 0.0, + "radius": 0.4, + "items": [ + { + "id": "bd", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.01, + "nx": 0, + "ny": 0, + "nz": -1, + "double": true + }, + { + "id": "bds", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.01, + "nx": 0, + "ny": 0, + "nz": -1, + "double": true + }, + { + "id": "ch", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.03, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "sh", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.04, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "lg", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.02, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "ss", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.04, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "cp", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.045, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "wa", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.05, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "cc", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.06, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "ca", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.07, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + } + ] + }, + { + "id": "leftitem", + "x": 0, + "y": 0, + "z": -0.29, + "radius": 0.3, + "items": [ + { + "id": "li", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.01, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + } + ] + }, + { + "id": "rightitem", + "x": 0, + "y": 0, + "z": -0.29, + "radius": 0.3, + "items": [ + { + "id": "ri", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.01, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + } + ] + }, + { + "id": "leftarm", + "x": -1, + "y": 0, + "z": -0.51, + "radius": 0.5, + "items": [ + { + "id": "lh", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.01, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "lhs", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.01, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "ls", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.02, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "lc", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.025, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + } + ] + }, + { + "id": "rightarm", + "x": 1, + "y": 0, + "z": -0.51, + "radius": 0.5, + "items": [ + { + "id": "rh", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.01, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "rhs", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.01, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "rs", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.02, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "rc", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.025, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + } + ] + }, + { + "id": "head", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.5, + "items": [ + { + "id": "hd", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.01, + "nx": 0, + "ny": 0, + "nz": -1, + "double": true + }, + { + "id": "fc", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.02, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "ey", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.03, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "hr", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.04, + "nx": 0, + "ny": 0, + "nz": -1, + "double": true + }, + { + "id": "hrb", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.05, + "nx": 0, + "ny": 0, + "nz": -1, + "double": true + }, + { + "id": "fa", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.06, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "ea", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.07, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "ha", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.08, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "he", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.09, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + } + ] + } + ] + }, + { + "id": "horizontal", + "bodyParts": [ + { + "id": "torso", + "x": 0, + "y": 0, + "z": 0.0, + "radius": 0.4, + "items": [ + { + "id": "bd", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.01, + "nx": 0, + "ny": 0, + "nz": -1, + "double": true + }, + { + "id": "bds", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.01, + "nx": 0, + "ny": 0, + "nz": -1, + "double": true + }, + { + "id": "ch", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.02, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "cp", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.025, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "sh", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.04, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "lg", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.03, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "ss", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.03, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "wa", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.05, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "cc", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.06, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "ca", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.07, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + } + ] + }, + { + "id": "leftitem", + "x": 0, + "y": 0, + "z": -0.29, + "radius": 0.3, + "items": [ + { + "id": "li", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.01, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + } + ] + }, + { + "id": "rightitem", + "x": 0, + "y": 0, + "z": -0.29, + "radius": 0.3, + "items": [ + { + "id": "ri", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.01, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + } + ] + }, + { + "id": "leftarm", + "x": -1, + "y": 0, + "z": -0.51, + "radius": 0.6, + "items": [ + { + "id": "lh", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.01, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "lhs", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.01, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "ls", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.02, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "lc", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.025, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + } + ] + }, + { + "id": "rightarm", + "x": 1, + "y": 0, + "z": -0.51, + "radius": 0.6, + "items": [ + { + "id": "rh", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.01, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "rhs", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.01, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "rs", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.02, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "rc", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.025, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + } + ] + }, + { + "id": "head", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.5, + "items": [ + { + "id": "hd", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.01, + "nx": 0, + "ny": 0, + "nz": -1, + "double": true + }, + { + "id": "fc", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.02, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "ey", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.03, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "hr", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.04, + "nx": 0, + "ny": 0, + "nz": -1, + "double": true + }, + { + "id": "hrb", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.05, + "nx": 0, + "ny": 0, + "nz": -1, + "double": true + }, + { + "id": "fa", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.06, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "ea", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.07, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "ha", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.08, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "he", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.09, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + } + ] + } + ] + }, + { + "id": "swhorizontal", + "bodyParts": [ + { + "id": "torso", + "x": 0, + "y": 0, + "z": 0.0, + "radius": 0.4, + "items": [ + { + "id": "bd", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.01, + "nx": 0, + "ny": 0, + "nz": -1, + "double": true + }, + { + "id": "bds", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.01, + "nx": 0, + "ny": 0, + "nz": -1, + "double": true + }, + { + "id": "ch", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.02, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "cp", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.025, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "sh", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.04, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "lg", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.03, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "ss", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.03, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "wa", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.05, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "cc", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.06, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "ca", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.07, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + } + ] + }, + { + "id": "leftitem", + "x": 0, + "y": 0, + "z": -0.29, + "radius": 0.3, + "items": [ + { + "id": "li", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.01, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + } + ] + }, + { + "id": "rightitem", + "x": 0, + "y": 0, + "z": -0.29, + "radius": 0.3, + "items": [ + { + "id": "ri", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.01, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + } + ] + }, + { + "id": "leftarm", + "x": -1, + "y": 0, + "z": -0.51, + "radius": 0.6, + "items": [ + { + "id": "lh", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.01, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "lhs", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.01, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "ls", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.02, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "lc", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.025, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + } + ] + }, + { + "id": "rightarm", + "x": 1, + "y": 0, + "z": -0.51, + "radius": 0.6, + "items": [ + { + "id": "rh", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.01, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "rhs", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.01, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "rs", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.02, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "rc", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.025, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + } + ] + }, + { + "id": "head", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.5, + "items": [ + { + "id": "hd", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.01, + "nx": 0, + "ny": 0, + "nz": -1, + "double": true + }, + { + "id": "fc", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.02, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "ey", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.03, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "hr", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.04, + "nx": 0, + "ny": 0, + "nz": -1, + "double": true + }, + { + "id": "hrb", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.05, + "nx": 0, + "ny": 0, + "nz": -1, + "double": true + }, + { + "id": "fa", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.06, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "ea", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.07, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "ha", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.08, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "he", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.09, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + } + ] + } + ] + }, + { + "id": "swim", + "bodyParts": [ + { + "id": "torso", + "x": 0, + "y": 0, + "z": 0.0, + "radius": 0.4, + "items": [ + { + "id": "bds", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.01, + "nx": 0, + "ny": 0, + "nz": -1, + "double": true + }, + { + "id": "ss", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.03, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + } + ] + }, + { + "id": "head", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.5, + "items": [ + { + "id": "hd", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.01, + "nx": 0, + "ny": 0, + "nz": -1, + "double": true + }, + { + "id": "fc", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.02, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "ey", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.03, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "hr", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.04, + "nx": 0, + "ny": 0, + "nz": -1, + "double": true + }, + { + "id": "hrb", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.05, + "nx": 0, + "ny": 0, + "nz": -1, + "double": true + }, + { + "id": "fa", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.06, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "ea", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.07, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "ha", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.08, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + }, + { + "id": "he", + "x": 0, + "y": 0, + "z": 0, + "radius": 0.09, + "nx": 0, + "ny": 0, + "nz": -1, + "double": false + } + ] + } + ] + } + ] + } +} \ No newline at end of file diff --git a/src/nitro/avatar/data/HabboAvatarPartSets.json b/src/nitro/avatar/data/HabboAvatarPartSets.json new file mode 100644 index 00000000..eba04fa2 --- /dev/null +++ b/src/nitro/avatar/data/HabboAvatarPartSets.json @@ -0,0 +1,418 @@ +{ + "partSets": { + "partSet": [ + { + "setType": "ri", + "flippedSetType": "ri" + }, + { + "setType": "ri", + "flippedSetType": "ri" + }, + { + "setType": "rh", + "flippedSetType": "lh" + }, + { + "setType": "rhs", + "flippedSetType": "lhs" + }, + { + "setType": "rs", + "swim": "0", + "flippedSetType": "ls" + }, + { + "setType": "rc", + "flippedSetType": "lc" + }, + { + "setType": "bd" + }, + { + "setType": "bds" + }, + { + "setType": "ss" + }, + { + "setType": "sh" + }, + { + "setType": "lg" + }, + { + "setType": "ch" + }, + { + "setType": "cp" + }, + { + "setType": "cc" + }, + { + "setType": "hd" + }, + { + "setType": "fc" + }, + { + "setType": "ey" + }, + { + "setType": "hr" + }, + { + "setType": "hrb", + "removeSetType": "hr" + }, + { + "setType": "li", + "flippedSetType": "li" + }, + { + "setType": "lh", + "flippedSetType": "rh" + }, + { + "setType": "lhs", + "flippedSetType": "rhs" + }, + { + "setType": "ls", + "flippedSetType": "rs" + }, + { + "setType": "lc", + "flippedSetType": "rc" + }, + { + "setType": "wa" + }, + { + "setType": "ea" + }, + { + "setType": "ca" + }, + { + "setType": "fa" + }, + { + "setType": "ha" + }, + { + "setType": "he" + } + ], + "activePartSets": [ + { + "id": "figure", + "activeParts": [ + { + "setType": "rh" + }, + { + "setType": "rh" + }, + { + "setType": "rhs" + }, + { + "setType": "rs" + }, + { + "setType": "rc" + }, + { + "setType": "bd" + }, + { + "setType": "bds" + }, + { + "setType": "ss" + }, + { + "setType": "sh" + }, + { + "setType": "lg" + }, + { + "setType": "ch" + }, + { + "setType": "cp" + }, + { + "setType": "cc" + }, + { + "setType": "wa" + }, + { + "setType": "hd" + }, + { + "setType": "fc" + }, + { + "setType": "ey" + }, + { + "setType": "hr" + }, + { + "setType": "hrb" + }, + { + "setType": "lh" + }, + { + "setType": "lhs" + }, + { + "setType": "ls" + }, + { + "setType": "lc" + }, + { + "setType": "ea" + }, + { + "setType": "ca" + }, + { + "setType": "fa" + }, + { + "setType": "ha" + }, + { + "setType": "he" + } + ] + }, + { + "id": "head", + "activeParts": [ + { + "setType": "hd" + }, + { + "setType": "fc" + }, + { + "setType": "ey" + }, + { + "setType": "hr" + }, + { + "setType": "hrb" + }, + { + "setType": "ea" + }, + { + "setType": "fa" + }, + { + "setType": "ha" + }, + { + "setType": "he" + } + ] + }, + { + "id": "speak", + "activeParts": [ + { + "setType": "hd" + }, + { + "setType": "hr" + }, + { + "setType": "hrb" + }, + { + "setType": "fc" + }, + { + "setType": "fa" + }, + { + "setType": "ha" + } + ] + }, + { + "id": "gesture", + "activeParts": [ + { + "setType": "ey" + }, + { + "setType": "fc" + } + ] + }, + { + "id": "eye", + "activeParts": [ + { + "setType": "ey" + } + ] + }, + { + "id": "handRight", + "activeParts": [ + { + "setType": "rh" + }, + { + "setType": "rhs" + }, + { + "setType": "rs" + }, + { + "setType": "rc" + }, + { + "setType": "ri" + } + ] + }, + { + "id": "handRightAndHead", + "activeParts": [ + { + "setType": "rh" + }, + { + "setType": "rhs" + }, + { + "setType": "rs" + }, + { + "setType": "rc" + }, + { + "setType": "ri" + }, + { + "setType": "ey" + }, + { + "setType": "fc" + }, + { + "setType": "hd" + } + ] + }, + { + "id": "handLeft", + "activeParts": [ + { + "setType": "lh" + }, + { + "setType": "lhs" + }, + { + "setType": "ls" + }, + { + "setType": "lc" + }, + { + "setType": "li" + } + ] + }, + { + "id": "walk", + "activeParts": [ + { + "setType": "bd" + }, + { + "setType": "bds" + }, + { + "setType": "ss" + }, + { + "setType": "lg" + }, + { + "setType": "lh" + }, + { + "setType": "lhs" + }, + { + "setType": "rh" + }, + { + "setType": "rhs" + }, + { + "setType": "ls" + }, + { + "setType": "lc" + }, + { + "setType": "rs" + }, + { + "setType": "rc" + }, + { + "setType": "sh" + } + ] + }, + { + "id": "sit", + "activeParts": [ + { + "setType": "bd" + }, + { + "setType": "bds" + }, + { + "setType": "ss" + }, + { + "setType": "lg" + }, + { + "setType": "sh" + }, + { + "setType": "cc" + } + ] + }, + { + "id": "itemRight", + "activeParts": [ + { + "setType": "ri" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/src/nitro/avatar/enum/AvatarAction.ts b/src/nitro/avatar/enum/AvatarAction.ts new file mode 100644 index 00000000..b53c2a0b --- /dev/null +++ b/src/nitro/avatar/enum/AvatarAction.ts @@ -0,0 +1,127 @@ +export class AvatarAction +{ + public static CARRY_OBJECT = 'cri'; + public static DANCE = 'dance'; + public static EFFECT = 'fx'; + public static EXPRESSION = 'expression'; + public static EXPRESSION_BLOW_A_KISS = 'blow'; + public static EXPRESSION_CRY = 'cry'; + public static EXPRESSION_IDLE = 'idle'; + public static EXPRESSION_LAUGH = 'laugh'; + public static EXPRESSION_RESPECT = 'respect'; + public static EXPRESSION_RIDE_JUMP = 'ridejump'; + public static EXPRESSION_SNOWBOARD_OLLIE = 'sbollie'; + public static EXPRESSION_SNOWBORD_360 = 'sb360'; + public static EXPRESSION_WAVE = 'wave'; + public static GESTURE = 'gest'; + public static GESTURE_AGGRAVATED = 'agr'; + public static GESTURE_SAD = 'sad'; + public static GESTURE_SMILE = 'sml'; + public static GESTURE_SURPRISED = 'srp'; + public static GUIDE_STATUS = 'guide'; + public static MUTED = 'muted'; + public static PET_GESTURE_BLINK = 'eyb'; + public static PET_GESTURE_CRAZY = 'crz'; + public static PET_GESTURE_JOY = 'joy'; + public static PET_GESTURE_MISERABLE = 'mis'; + public static PET_GESTURE_PUZZLED = 'puz'; + public static PET_GESTURE_TONGUE = 'tng'; + public static PLAYING_GAME = 'playing_game'; + public static POSTURE = 'posture'; + public static POSTURE_FLOAT = 'float'; + public static POSTURE_LAY = 'lay'; + public static POSTURE_SIT = 'sit'; + public static POSTURE_STAND = 'std'; + public static POSTURE_SWIM = 'swim'; + public static POSTURE_WALK = 'mv'; + public static SIGN = 'sign'; + public static SLEEP = 'sleep'; + public static SNOWWAR_DIE_BACK = 'swdieback'; + public static SNOWWAR_DIE_FRONT = 'swdiefront'; + public static SNOWWAR_PICK = 'swpick'; + public static SNOWWAR_RUN = 'swrun'; + public static SNOWWAR_THROW = 'swthrow'; + public static TALK = 'talk'; + public static BLINK = 'blink'; + public static TYPING = 'typing'; + public static USE_OBJECT = 'usei'; + public static VOTE = 'vote'; + + public static GESTURE_MAP = [ '', AvatarAction.GESTURE_SMILE, AvatarAction.GESTURE_AGGRAVATED, AvatarAction.GESTURE_SURPRISED, AvatarAction.GESTURE_SAD, AvatarAction.PET_GESTURE_JOY, AvatarAction.PET_GESTURE_CRAZY, AvatarAction.PET_GESTURE_TONGUE, AvatarAction.PET_GESTURE_BLINK, AvatarAction.PET_GESTURE_MISERABLE, AvatarAction.PET_GESTURE_PUZZLED ]; + + public static EXPRESSION_MAP = [ '', AvatarAction.EXPRESSION_WAVE, AvatarAction.EXPRESSION_BLOW_A_KISS, AvatarAction.EXPRESSION_LAUGH, AvatarAction.EXPRESSION_CRY, AvatarAction.EXPRESSION_IDLE, AvatarAction.DANCE, AvatarAction.EXPRESSION_RESPECT, AvatarAction.EXPRESSION_SNOWBOARD_OLLIE, AvatarAction.EXPRESSION_SNOWBORD_360, AvatarAction.EXPRESSION_RIDE_JUMP ]; + + public static getExpressionTimeout(expressionId: number): number + { + expressionId = parseInt(expressionId as any); + + switch(expressionId) + { + case 1: + return 5000; + case 2: + return 1400; + case 3: + return 2000; + case 4: + return 2000; + case 5: + return 0; + case 6: + return 700; + case 7: + return 2000; + case 8: + return 1500; + case 9: + return 1500; + case 10: + return 1500; + default: + return 0; + } + } + + public static getExpressionId(expression: string): number + { + return AvatarAction.EXPRESSION_MAP.indexOf(expression); + } + + public static getExpression(expressionId: number): string + { + if(expressionId > AvatarAction.EXPRESSION_MAP.length) return null; + + return AvatarAction.EXPRESSION_MAP[expressionId]; + } + + public static getGestureId(gesture: string): number + { + return AvatarAction.GESTURE_MAP.indexOf(gesture); + } + + public static getGesture(gestureId: number): string + { + if(gestureId > AvatarAction.GESTURE_MAP.length) return null; + + return AvatarAction.GESTURE_MAP[gestureId]; + } + + public static idToAvatarActionState(id: string): string + { + if(id === 'Lay') return 'lay'; + if(id === 'Float') return 'float'; + if(id === 'Swim') return 'swim'; + if(id === 'Sit') return 'sit'; + if(id === 'Respect') return 'respect'; + if(id === 'Wave') return 'wave'; + if(id === 'Idle') return 'idle'; + if(id === 'Dance') return 'dance'; + if(id === 'UseItem') return 'usei'; + if(id === 'CarryItem') return 'cri'; + if(id === 'Talk') return 'talk'; + if(id === 'Sleep') return 'Sleep'; + if(id === 'Move') return 'mv'; + + return 'std'; + } +} \ No newline at end of file diff --git a/src/nitro/avatar/enum/AvatarDirectionAngle.ts b/src/nitro/avatar/enum/AvatarDirectionAngle.ts new file mode 100644 index 00000000..cb383d9b --- /dev/null +++ b/src/nitro/avatar/enum/AvatarDirectionAngle.ts @@ -0,0 +1,7 @@ +export class AvatarDirectionAngle +{ + public static DIRECTION_TO_ANGLE: number[] = [45, 90, 135, 180, 225, 270, 315, 0]; //_Str_2204 + public static DIRECTION_IS_FLIPPED: boolean[] = [false, false, false, false, true, true, true, false]; //_Str_1859 + public static MIN_DIRECTION: number = 0; //_Str_1562 + public static MAX_DIRECTION: number = 7; //_Str_1257 +} \ No newline at end of file diff --git a/src/nitro/avatar/enum/AvatarEditorFigureCategory.ts b/src/nitro/avatar/enum/AvatarEditorFigureCategory.ts new file mode 100644 index 00000000..4c53f891 --- /dev/null +++ b/src/nitro/avatar/enum/AvatarEditorFigureCategory.ts @@ -0,0 +1,10 @@ +export class AvatarEditorFigureCategory +{ + public static GENERIC: string = 'hd'; + public static HEAD: string = 'head'; + public static TORSO: string = 'torso'; + public static LEGS: string = 'legs'; + public static HOTLOOKS: string = 'hotlooks'; + public static WARDROBE: string = 'wardrobe'; + public static EFFECTS: string = 'effects'; +} \ No newline at end of file diff --git a/src/nitro/avatar/enum/AvatarEditorInstanceId.ts b/src/nitro/avatar/enum/AvatarEditorInstanceId.ts new file mode 100644 index 00000000..d4c8ace3 --- /dev/null +++ b/src/nitro/avatar/enum/AvatarEditorInstanceId.ts @@ -0,0 +1,7 @@ +export class AvatarEditorInstanceId +{ + public static _Str_3350: number = 0; + public static _Str_7195: number = 1; + public static _Str_17909: number = 2; + public static _Str_16370: number = 3; +} \ No newline at end of file diff --git a/src/nitro/avatar/enum/AvatarEditorSideCategory.ts b/src/nitro/avatar/enum/AvatarEditorSideCategory.ts new file mode 100644 index 00000000..13e3304d --- /dev/null +++ b/src/nitro/avatar/enum/AvatarEditorSideCategory.ts @@ -0,0 +1,5 @@ +export class AvatarEditorSideCategory +{ + public static NOTHING: string = 'nothing'; + public static WARDROBE: string = 'wardrobe'; +} \ No newline at end of file diff --git a/src/nitro/avatar/enum/AvatarFigurePartType.ts b/src/nitro/avatar/enum/AvatarFigurePartType.ts new file mode 100644 index 00000000..9ac466ed --- /dev/null +++ b/src/nitro/avatar/enum/AvatarFigurePartType.ts @@ -0,0 +1,29 @@ +export class AvatarFigurePartType +{ + public static BODY: string = 'bd'; + public static SHOES: string = 'sh'; + public static LEGS: string = 'lg'; + public static CHEST: string = 'ch'; + public static WAIST_ACCESSORY: string = 'wa'; + public static CHEST_ACCESSORY: string = 'ca'; + public static HEAD: string = 'hd'; + public static HAIR: string = 'hr'; + public static FACE_ACCESSORY: string = 'fa'; + public static EYE_ACCESSORY: string = 'ea'; + public static HEAD_ACCESSORY: string = 'ha'; + public static HEAD_ACCESSORY_EXTRA: string = 'he'; + public static COAT_CHEST: string = 'cc'; + public static CHEST_PRINT: string = 'cp'; + public static LEFT_HAND_ITEM: string = 'li'; + public static LEFT_HAND: string = 'lh'; + public static LEFT_SLEEVE: string = 'ls'; + public static RIGHT_HAND: string = 'rh'; + public static RIGHT_SLEEVE: string = 'rs'; + public static FACE: string = 'fc'; + public static EYES: string = 'ey'; + public static HAIR_BIG: string = 'hrb'; + public static RIGHT_HAND_ITEM: string = 'ri'; + public static LEFT_COAT_SLEEVE: string = 'lc'; + public static RIGHT_COAT_SLEEVE: string = 'rc'; + public static _Str_1286: string[] = [ AvatarFigurePartType.SHOES, AvatarFigurePartType.LEGS, AvatarFigurePartType.CHEST, AvatarFigurePartType.WAIST_ACCESSORY, AvatarFigurePartType.CHEST_ACCESSORY, AvatarFigurePartType.HEAD, AvatarFigurePartType.HAIR, AvatarFigurePartType.FACE_ACCESSORY, AvatarFigurePartType.EYE_ACCESSORY, AvatarFigurePartType.HEAD_ACCESSORY, AvatarFigurePartType.HEAD_ACCESSORY_EXTRA, AvatarFigurePartType.COAT_CHEST, AvatarFigurePartType.CHEST_PRINT ]; +} \ No newline at end of file diff --git a/src/nitro/avatar/enum/AvatarGuideStatus.ts b/src/nitro/avatar/enum/AvatarGuideStatus.ts new file mode 100644 index 00000000..35004c28 --- /dev/null +++ b/src/nitro/avatar/enum/AvatarGuideStatus.ts @@ -0,0 +1,6 @@ +export class AvatarGuideStatus +{ + public static NONE: number = 0; + public static GUIDE: number = 1; + public static REQUESTER: number = 2; +} \ No newline at end of file diff --git a/src/nitro/avatar/enum/AvatarScaleType.ts b/src/nitro/avatar/enum/AvatarScaleType.ts new file mode 100644 index 00000000..59334952 --- /dev/null +++ b/src/nitro/avatar/enum/AvatarScaleType.ts @@ -0,0 +1,5 @@ +export class AvatarScaleType +{ + public static LARGE: string = 'h'; + public static SMALL: string = 'sh'; +} \ No newline at end of file diff --git a/src/nitro/avatar/enum/AvatarSetType.ts b/src/nitro/avatar/enum/AvatarSetType.ts new file mode 100644 index 00000000..38df0af9 --- /dev/null +++ b/src/nitro/avatar/enum/AvatarSetType.ts @@ -0,0 +1,6 @@ +export class AvatarSetType +{ + public static FULL: string = 'full'; + public static HEAD: string = 'head'; + public static BODY: string = 'body'; +} \ No newline at end of file diff --git a/src/nitro/avatar/enum/GeometryType.ts b/src/nitro/avatar/enum/GeometryType.ts new file mode 100644 index 00000000..30607459 --- /dev/null +++ b/src/nitro/avatar/enum/GeometryType.ts @@ -0,0 +1,8 @@ +export class GeometryType +{ + public static VERTICAL: string = 'vertical'; + public static SITTING: string = 'sitting'; + public static HORIZONTAL: string = 'horizontal'; + public static SWIM: string = 'swim'; + public static SNOWWARS_HORIZONTAL: string = 'swhorizontal'; +} \ No newline at end of file diff --git a/src/nitro/avatar/enum/RenderMode.ts b/src/nitro/avatar/enum/RenderMode.ts new file mode 100644 index 00000000..48147d30 --- /dev/null +++ b/src/nitro/avatar/enum/RenderMode.ts @@ -0,0 +1,7 @@ +export class RenderMode +{ + public static TOOL: string = 'tool'; + public static COMPONENT: string = 'component'; + public static ONLINE_TOOL: string = 'online_tool'; + public static LOCAL_ONLY: string = 'local_only'; +} \ No newline at end of file diff --git a/src/nitro/avatar/events/AvatarRenderEffectLibraryEvent.ts b/src/nitro/avatar/events/AvatarRenderEffectLibraryEvent.ts new file mode 100644 index 00000000..68041bd9 --- /dev/null +++ b/src/nitro/avatar/events/AvatarRenderEffectLibraryEvent.ts @@ -0,0 +1,21 @@ +import { NitroEvent } from '../../../core/events/NitroEvent'; +import { EffectAssetDownloadLibrary } from '../EffectAssetDownloadLibrary'; + +export class AvatarRenderEffectLibraryEvent extends NitroEvent +{ + public static DOWNLOAD_COMPLETE: string = 'ARELE_DOWNLOAD_COMPLETE'; + + private _library: EffectAssetDownloadLibrary; + + constructor(type: string, library: EffectAssetDownloadLibrary) + { + super(type); + + this._library = library; + } + + public get library(): EffectAssetDownloadLibrary + { + return this._library; + } +} \ No newline at end of file diff --git a/src/nitro/avatar/events/AvatarRenderEvent.ts b/src/nitro/avatar/events/AvatarRenderEvent.ts new file mode 100644 index 00000000..d3292e68 --- /dev/null +++ b/src/nitro/avatar/events/AvatarRenderEvent.ts @@ -0,0 +1,4 @@ +export class AvatarRenderEvent +{ + public static AVATAR_RENDER_READY: string = 'AVATAR_RENDER_READY'; +} \ No newline at end of file diff --git a/src/nitro/avatar/events/AvatarRenderLibraryEvent.ts b/src/nitro/avatar/events/AvatarRenderLibraryEvent.ts new file mode 100644 index 00000000..caa80d5c --- /dev/null +++ b/src/nitro/avatar/events/AvatarRenderLibraryEvent.ts @@ -0,0 +1,21 @@ +import { NitroEvent } from '../../../core/events/NitroEvent'; +import { AvatarAssetDownloadLibrary } from '../AvatarAssetDownloadLibrary'; + +export class AvatarRenderLibraryEvent extends NitroEvent +{ + public static DOWNLOAD_COMPLETE: string = 'ARLE_DOWNLOAD_COMPLETE'; + + private _library: AvatarAssetDownloadLibrary; + + constructor(type: string, library: AvatarAssetDownloadLibrary) + { + super(type); + + this._library = library; + } + + public get library(): AvatarAssetDownloadLibrary + { + return this._library; + } +} \ No newline at end of file diff --git a/src/nitro/avatar/figuredata/FigureData.ts b/src/nitro/avatar/figuredata/FigureData.ts new file mode 100644 index 00000000..4586660e --- /dev/null +++ b/src/nitro/avatar/figuredata/FigureData.ts @@ -0,0 +1,311 @@ +import { IAvatarImageListener } from '../IAvatarImageListener'; +import { FigureDataView } from './FigureDataView'; + +export class FigureData implements IAvatarImageListener +{ + public static M: string = 'M'; + public static F: string = 'F'; + public static U: string = 'U'; + public static H: string = 'h'; + public static STD: string = 'std'; + public static _Str_2028: string = '0'; + public static FACE: string = 'hd'; + public static HR: string = 'hr'; + public static HA: string = 'ha'; + public static HE: string = 'he'; + public static EA: string = 'ea'; + public static FA: string = 'fa'; + public static CC: string = 'cc'; + public static CH: string = 'ch'; + public static CHEST_ACCESSORIES: string = 'ca'; + public static CHEST_PRINTS: string = 'cp'; + public static LG: string = 'lg'; + public static SH: string = 'sh'; + public static WA: string = 'wa'; + + private _view: FigureDataView; + private _data: Map; + private _colors: Map; + private _gender: string = 'M'; + private _isDisposed: boolean; + private _direction: number = 4; + private _avatarEffectType: number = -1; + + constructor() + { + this._direction = FigureDataView._Str_9887; + this._view = new FigureDataView(this); + } + + public loadAvatarData(figureString: string, gender: string): void + { + this._data = new Map(); + this._colors = new Map(); + this._gender = gender; + + this.parseFigureString(figureString); + this.updateView(); + } + + public dispose(): void + { + this._data = null; + this._colors = null; + this._isDisposed = true; + + if(this._view) + { + this._view.dispose(); + + this._view = null; + } + } + + public get disposed(): boolean + { + return this._isDisposed; + } + + private parseFigureString(figure: string): void + { + if(!figure) return; + + const sets = figure.split('.'); + + if(!sets || !sets.length) return; + + for(const set of sets) + { + const parts = set.split('-'); + + if(!parts.length) continue; + + const setType = parts[0]; + const setId = parseInt(parts[1]); + const colorIds: number[] = []; + + let offset = 2; + + while(offset < parts.length) + { + colorIds.push(parseInt(parts[offset])); + + offset++; + } + + if(!colorIds.length) colorIds.push(0); + + this.savePartSetId(setType, setId, false); + this.savePartSetColourId(setType, colorIds, false); + } + } + + public getPartSetId(k: string): number + { + const existing = this._data.get(k); + + if(existing !== undefined) return existing; + + return -1; + } + + public getColourIds(k: string): number[] + { + const existing = this._colors.get(k); + + if(existing !== undefined) return existing; + + return []; + // return [this._avatarEditor._Str_24919(k)]; + } + + public getFigureString(): string + { + let figureString = ''; + const setParts: string[] = []; + + for(const [ setType, setId ] of this._data.entries()) + { + const colorIds = this._colors.get(setType); + + let setPart = ((setType + '-') + setId); + + if(colorIds && colorIds.length) + { + let i = 0; + + while(i < colorIds.length) + { + setPart = (setPart + ('-' + colorIds[i])); + + i++; + } + } + + setParts.push(setPart); + } + + let i = 0; + + while(i < setParts.length) + { + figureString = (figureString + setParts[i]); + + if(i < (setParts.length - 1)) figureString = (figureString + '.'); + + i++; + } + + return figureString; + } + + public savePartData(k: string, _arg_2: number, _arg_3: number[], _arg_4: boolean = false): void + { + this.savePartSetId(k, _arg_2, _arg_4); + this.savePartSetColourId(k, _arg_3, _arg_4); + } + + private savePartSetId(k: string, _arg_2: number, _arg_3: boolean = true): void + { + switch(k) + { + case FigureData.FACE: + case FigureData.HR: + case FigureData.HA: + case FigureData.HE: + case FigureData.EA: + case FigureData.FA: + case FigureData.CH: + case FigureData.CC: + case FigureData.CHEST_ACCESSORIES: + case FigureData.CHEST_PRINTS: + case FigureData.LG: + case FigureData.SH: + case FigureData.WA: + if(_arg_2 >= 0) + { + this._data.set(k, _arg_2); + } + else + { + this._data.delete(k); + } + break; + } + + if(_arg_3) this.updateView(); + } + + public savePartSetColourId(k: string, _arg_2: number[], _arg_3: boolean = true): void + { + switch(k) + { + case FigureData.FACE: + case FigureData.HR: + case FigureData.HA: + case FigureData.HE: + case FigureData.EA: + case FigureData.FA: + case FigureData.CH: + case FigureData.CC: + case FigureData.CHEST_ACCESSORIES: + case FigureData.CHEST_PRINTS: + case FigureData.LG: + case FigureData.SH: + case FigureData.WA: + this._colors.set(k, _arg_2); + break; + } + + if(_arg_3) this.updateView(); + } + + public getFigureStringWithFace(k: number, override = true): string + { + let figureString = ''; + + const setTypes: string[] = [ FigureData.FACE ]; + const figureSets: string[] = []; + + for(const setType of setTypes) + { + const colors = this._colors.get(setType); + + if(colors === undefined) continue; + + let setId = this._data.get(setType); + + if((setType === FigureData.FACE) && override) setId = k; + + let figureSet = ((setType + '-') + setId); + + if(setId >= 0) + { + let i = 0; + + while(i < colors.length) + { + figureSet = (figureSet + ('-' + colors[i])); + + i++; + } + } + + figureSets.push(figureSet); + } + + let i = 0; + + while(i < figureSets.length) + { + figureString = (figureString + figureSets[i]); + + if(i < (figureSets.length - 1)) figureString = (figureString + '.'); + + i++; + } + + return figureString; + } + + public updateView(): void + { + this._view.update(this.getFigureString(), this._avatarEffectType, this._direction); + } + + public get view(): FigureDataView + { + return this._view; + } + + public get gender(): string + { + return this._gender; + } + + public resetFigure(k: string): void + { + this.updateView(); + } + + public set avatarEffectType(k: number) + { + this._avatarEffectType = k; + } + + public get avatarEffectType(): number + { + return this._avatarEffectType; + } + + public get direction(): number + { + return this._direction; + } + + public set direction(k: number) + { + this._direction = k; + this.updateView(); + } +} \ No newline at end of file diff --git a/src/nitro/avatar/figuredata/FigureDataView.ts b/src/nitro/avatar/figuredata/FigureDataView.ts new file mode 100644 index 00000000..6d794f65 --- /dev/null +++ b/src/nitro/avatar/figuredata/FigureDataView.ts @@ -0,0 +1,43 @@ +import { IAvatarImageListener } from '../IAvatarImageListener'; +import { FigureData } from './FigureData'; + +export class FigureDataView implements IAvatarImageListener +{ + public static _Str_9887: number = 4; + + private _model: FigureData; + private _figureString: string; + private _isDisposed: boolean; + + constructor(k: FigureData) + { + this._model = k; + this._figureString = null; + this._isDisposed = false; + } + + public dispose(): void + { + this._isDisposed = true; + } + + public update(k: string, effectId: number = 0, direction: number = 4): void + { + this._figureString = k; + } + + public resetFigure(k: string): void + { + if(k !== this._figureString) return; + } + + public get disposed(): boolean + { + return this._isDisposed; + } + + public get figureString(): string + { + return this._figureString; + } +} \ No newline at end of file diff --git a/src/nitro/avatar/geometry/AvatarModelGeometry.ts b/src/nitro/avatar/geometry/AvatarModelGeometry.ts new file mode 100644 index 00000000..621209c5 --- /dev/null +++ b/src/nitro/avatar/geometry/AvatarModelGeometry.ts @@ -0,0 +1,287 @@ +import { IAvatarImage } from '../IAvatarImage'; +import { AvatarCanvas } from '../structure/AvatarCanvas'; +import { AvatarSet } from './AvatarSet'; +import { GeometryBodyPart } from './GeometryBodyPart'; +import { Matrix4x4 } from './Matrix4x4'; +import { Vector3D } from './Vector3D'; + +export class AvatarModelGeometry +{ + private _camera: Vector3D; + private _avatarSet: AvatarSet; + private _geometryTypes: Map>; + private _itemIdToBodyPartMap: Map>; + private _transformation: Matrix4x4; + private _canvases: Map>; + + constructor(k: any) + { + this._camera = new Vector3D(0, 0, 10); + this._avatarSet = new AvatarSet(k.avatarSets[0]); + this._geometryTypes = new Map(); + this._itemIdToBodyPartMap = new Map(); + this._transformation = new Matrix4x4(); + this._canvases = new Map(); + + const camera = k.camera; + + if(camera) + { + this._camera.x = parseFloat(camera.x); + this._camera.y = parseFloat(camera.y); + this._camera.z = parseFloat(camera.z); + } + + if(k.canvases && (k.canvases.length > 0)) + { + for(const canvas of k.canvases) + { + if(!canvas) continue; + + const scale = canvas.scale; + const geometries = new Map(); + + if(canvas.geometries && (canvas.geometries.length > 0)) + { + for(const geometry of canvas.geometries) + { + if(!geometry) continue; + + const avatarCanvas = new AvatarCanvas(geometry, scale); + + geometries.set(avatarCanvas.id, avatarCanvas); + } + } + + this._canvases.set(scale, geometries); + } + } + + if(k.types && (k.types.length > 0)) + { + for(const type of k.types) + { + if(!type) continue; + + const bodyParts: Map = new Map(); + const itemIds: Map = new Map(); + + if(type.bodyParts && (type.bodyParts.length > 0)) + { + for(const bodyPart of type.bodyParts) + { + if(!bodyPart) continue; + + const geometryBodyPart = new GeometryBodyPart(bodyPart); + + bodyParts.set(geometryBodyPart.id, geometryBodyPart); + + for(const part of geometryBodyPart._Str_1456(null)) + { + itemIds.set(part, geometryBodyPart); + } + } + } + + this._geometryTypes.set(type.id, bodyParts); + this._itemIdToBodyPartMap.set(type.id, itemIds); + } + } + } + + public _Str_2101(k: IAvatarImage): void + { + for(const geometry of this._geometryTypes.values()) + { + if(!geometry) continue; + + for(const part of geometry.values()) + { + if(!part) continue; + + part._Str_2004(k); + } + } + } + + public _Str_1307(k: string): string[] + { + const avatarSet = this._avatarSet._Str_1498(k); + + if(!avatarSet) return []; + + return avatarSet._Str_755(); + } + + public _Str_1939(k: string): boolean + { + const avatarSet = this._avatarSet._Str_1498(k); + + if(!avatarSet) return false; + + return avatarSet._Str_779; + } + + public _Str_1664(k: string, _arg_2: string): AvatarCanvas + { + const canvas = this._canvases.get(k); + + if(!canvas) return null; + + return (canvas.get(_arg_2) || null); + } + + private _Str_1342(k: string): boolean + { + const existing = this._geometryTypes.get(k); + + if(existing) return true; + + return false; + } + + private _Str_1332(k: string, _arg_2: string): boolean + { + if(this._Str_1342(k)) + { + const existing = this._geometryTypes.get(k); + + if(existing && existing.get(_arg_2)) return true; + } + + return false; + } + + private _Str_2072(k: string): string[] + { + const parts = this._Str_1280(k); + + const types = []; + + if(parts) + { + for(const part of parts.values()) + { + if(!part) continue; + + types.push(part.id); + } + } + + return types; + } + + private _Str_1280(k: string): Map + { + if(this._Str_1342(k)) return this._geometryTypes.get(k); + + return new Map(); + } + + public _Str_1919(k: string, _arg_2: string): GeometryBodyPart + { + return (this._Str_1280(k).get(_arg_2) || null); + } + + public _Str_1701(k: string, _arg_2: string, _arg_3:IAvatarImage): GeometryBodyPart + { + const itemIds = this._itemIdToBodyPartMap.get(k); + + if(itemIds) + { + const part = itemIds.get(_arg_2); + + if(part) return part; + + const parts = this._Str_1280(k); + + if(parts) + { + for(const part of parts.values()) + { + if(!part) continue; + + if(part._Str_2030(_arg_2, _arg_3)) return part; + } + } + } + + return null; + } + + private _Str_1787(k: Map, _arg_2: string): GeometryBodyPart[] + { + const parts = this._Str_1307(_arg_2); + const geometryParts = []; + + for(const part of parts) + { + if(!part) continue; + + const bodyPart = k.get(part); + + if(bodyPart) + { + geometryParts.push(bodyPart); + } + } + + return geometryParts; + } + + public _Str_2250(k: string, _arg_2: number, _arg_3: string): string[] + { + if(!_arg_3) return []; + + const geometryParts = this._Str_1280(_arg_3); + const parts = this._Str_1787(geometryParts, k); + const sets: [ number, GeometryBodyPart ][] = []; + const ids: string[] = []; + + this._transformation = Matrix4x4._Str_1560(_arg_2); + + for(const part of parts.values()) + { + if(!part) continue; + + part._Str_1101(this._transformation); + + sets.push([ part._Str_1522(this._camera), part ]); + } + + sets.sort((a, b) => + { + const partA = a[0]; + const partB = b[0]; + + if(partA < partB) return -1; + + if(partA > partB) return 1; + + return 0; + }); + + for(const set of sets) + { + if(!set) continue; + + ids.push(set[1].id); + } + + return ids; + } + + public _Str_713(k: string, _arg_2: string, _arg_3: number, _arg_4: any[], _arg_5:IAvatarImage): string[] + { + if(this._Str_1332(k, _arg_2)) + { + const part = this._Str_1280(k).get(_arg_2); + + this._transformation = Matrix4x4._Str_1560(_arg_3); + + return part._Str_713(this._transformation, this._camera, _arg_4, _arg_5); + } + + return []; + } +} \ No newline at end of file diff --git a/src/nitro/avatar/geometry/AvatarSet.ts b/src/nitro/avatar/geometry/AvatarSet.ts new file mode 100644 index 00000000..f22c2702 --- /dev/null +++ b/src/nitro/avatar/geometry/AvatarSet.ts @@ -0,0 +1,92 @@ +export class AvatarSet +{ + private _id: string; + private _isMain: boolean; + private _avatarSets: Map; + private _bodyParts: string[]; + private _allBodyParts: string[]; + + constructor(k: any) + { + this._id = k.id; + this._isMain = k.main || false; + this._avatarSets = new Map(); + this._bodyParts = []; + this._allBodyParts = []; + + if(k.avatarSets && (k.avatarSets.length > 0)) + { + for(const avatarSet of k.avatarSets) + { + if(!avatarSet) continue; + + const set = new AvatarSet(avatarSet); + + this._avatarSets.set(set.id, set); + } + } + + if(k.bodyParts && (k.bodyParts.length > 0)) + { + for(const bodyPart of k.bodyParts) + { + if(!bodyPart) continue; + + this._bodyParts.push(bodyPart.id); + } + } + + let bodyParts = this._bodyParts.concat(); + + for(const avatarSet of this._avatarSets.values()) + { + if(!avatarSet) continue; + + bodyParts = bodyParts.concat(avatarSet._Str_755()); + } + + this._allBodyParts = bodyParts; + } + + public _Str_1498(k: string): AvatarSet + { + if(k === this._id) return this; + + for(const avatarSet of this._avatarSets.values()) + { + if(!avatarSet) continue; + + if(!avatarSet._Str_1498(k)) continue; + + return avatarSet; + } + + return null; + } + + public _Str_755(): string[] + { + return this._allBodyParts.concat(); + } + + public get id(): string + { + return this._id; + } + + public get _Str_779(): boolean + { + if(this._isMain) return true; + + for(const avatarSet of this._avatarSets.values()) + { + if(!avatarSet) continue; + + if(!avatarSet._Str_779) continue; + + return true; + } + + return false; + } +} \ No newline at end of file diff --git a/src/nitro/avatar/geometry/GeometryBodyPart.ts b/src/nitro/avatar/geometry/GeometryBodyPart.ts new file mode 100644 index 00000000..ef82d5d2 --- /dev/null +++ b/src/nitro/avatar/geometry/GeometryBodyPart.ts @@ -0,0 +1,194 @@ +import { IAvatarImage } from '../IAvatarImage'; +import { GeometryItem } from './GeometryItem'; +import { Matrix4x4 } from './Matrix4x4'; +import { Node3D } from './Node3D'; +import { Vector3D } from './Vector3D'; + +export class GeometryBodyPart extends Node3D +{ + private _id: string; + private _radius: number; + private _parts: Map; + private _dynamicParts: Map; + + constructor(k: any) + { + super(parseFloat(k.x), parseFloat(k.y), parseFloat(k.z)); + + this._id = k.id; + this._radius = parseFloat(k.radius); + this._parts = new Map(); + this._dynamicParts = new Map(); + + if(k.items && (k.items.length > 0)) + { + for(const item of k.items) + { + if(!item) continue; + + const geometryItem = new GeometryItem(item); + + this._parts.set(geometryItem.id, geometryItem); + } + } + } + + public _Str_1883(k: IAvatarImage): GeometryItem[] + { + const existing = this._dynamicParts.get(k); + const parts: GeometryItem[] = []; + + if(existing) + { + for(const index in existing) + { + const item = existing[index]; + + if(!item) continue; + + parts.push(item); + } + } + + return parts; + } + + public _Str_1456(k: IAvatarImage): string[] + { + const ids: string[] = []; + + for(const part of this._parts.values()) + { + if(!part) continue; + + ids.push(part.id); + } + + if(k) + { + const existing = this._dynamicParts.get(k); + + if(existing) + { + for(const index in existing) + { + const part = existing[index]; + + if(!part) continue; + + ids.push(part.id); + } + } + } + + return ids; + } + + public _Str_2004(k: IAvatarImage): boolean + { + this._dynamicParts.delete(k); + + return true; + } + + public _Str_2020(k: any, _arg_2: IAvatarImage): boolean + { + if(this._Str_2030(k.id, _arg_2)) return false; + + let existing = this._dynamicParts.get(_arg_2); + + if(!existing) + { + existing = {}; + + this._dynamicParts.set(_arg_2, existing); + } + + existing[k.id] = new GeometryItem(k, true); + + return true; + } + + public _Str_2030(k: string, _arg_2: IAvatarImage): boolean + { + let existingPart = (this._parts.get(k) || null); + + if(!existingPart && (this._dynamicParts.get(_arg_2) !== undefined)) + { + existingPart = (this._dynamicParts.get(_arg_2)[k] || null); + } + + return (existingPart !== null); + } + + public _Str_713(k: Matrix4x4, _arg_2: Vector3D, _arg_3: any[], _arg_4: IAvatarImage): string[] + { + const parts: [ number, GeometryItem ][] = []; + + for(const part of this._parts.values()) + { + if(!part) continue; + + part._Str_1101(k); + + parts.push([ part._Str_1522(_arg_2), part ]); + } + + const existingDynamic = this._dynamicParts.get(_arg_4); + + if(existingDynamic) + { + for(const index in existingDynamic) + { + const part = existingDynamic[index]; + + if(!part) continue; + + part._Str_1101(k); + + parts.push([ part._Str_1522(_arg_2), part ]); + } + } + + parts.sort((a, b) => + { + const partA = a[0]; + const partB = b[0]; + + if(partA < partB) return -1; + + if(partA > partB) return 1; + + return 0; + }); + + const partIds: string[] = []; + + for(const part of parts) + { + if(!part) continue; + + partIds.push(part[1].id); + } + + return partIds; + } + + public _Str_1522(k: Vector3D): number + { + const _local_2 = Math.abs(((k.z - this._Str_1604.z) - this._radius)); + const _local_3 = Math.abs(((k.z - this._Str_1604.z) + this._radius)); + + return Math.min(_local_2, _local_3); + } + + public get id(): string + { + return this._id; + } + + public get radius(): number + { + return this._radius; + } +} \ No newline at end of file diff --git a/src/nitro/avatar/geometry/GeometryItem.ts b/src/nitro/avatar/geometry/GeometryItem.ts new file mode 100644 index 00000000..ee2b6e54 --- /dev/null +++ b/src/nitro/avatar/geometry/GeometryItem.ts @@ -0,0 +1,55 @@ +import { Node3D } from './Node3D'; +import { Vector3D } from './Vector3D'; + +export class GeometryItem extends Node3D +{ + private _id: string; + private _radius: number; + private _normal: Vector3D; + private _isDoubleSided: boolean; + private _isDynamic: boolean; + + constructor(k: any, _arg_2: boolean = false) + { + super(parseFloat(k.x), parseFloat(k.y), parseFloat(k.z)); + + this._id = k.id; + this._radius = parseFloat(k.radius); + this._normal = new Vector3D(parseFloat(k.nx), parseFloat(k.ny), parseFloat(k.nz)); + this._isDoubleSided = k.double || false; + this._isDynamic = _arg_2; + } + + public _Str_1522(k: Vector3D): number + { + const _local_2 = Math.abs(((k.z - this._Str_1604.z) - this._radius)); + const _local_3 = Math.abs(((k.z - this._Str_1604.z) + this._radius)); + + return Math.min(_local_2, _local_3); + } + + public get id(): string + { + return this._id; + } + + public get normal(): Vector3D + { + return this._normal; + } + + public get _Str_2207(): boolean + { + return this._isDoubleSided; + } + + public toString(): string + { + return ((((this._id + ': ') + this.location) + ' - ') + this._Str_1604); + } + + public get _Str_1457(): boolean + { + return this._isDynamic; + } +} \ No newline at end of file diff --git a/src/nitro/avatar/geometry/Matrix4x4.ts b/src/nitro/avatar/geometry/Matrix4x4.ts new file mode 100644 index 00000000..c248ea5d --- /dev/null +++ b/src/nitro/avatar/geometry/Matrix4x4.ts @@ -0,0 +1,133 @@ +import { Vector3D } from './Vector3D'; + +export class Matrix4x4 +{ + public static IDENTITY:Matrix4x4 = new Matrix4x4(1, 0, 0, 0, 1, 0, 0, 0, 1); + private static TOLERANS: number = 1E-18; + + private _data: number[]; + + constructor(k: number = 0, _arg_2: number = 0, _arg_3: number = 0, _arg_4: number = 0, _arg_5: number = 0, _arg_6: number = 0, _arg_7: number = 0, _arg_8: number = 0, _arg_9: number = 0) + { + this._data = [k, _arg_2, _arg_3, _arg_4, _arg_5, _arg_6, _arg_7, _arg_8, _arg_9]; + } + + public static _Str_1869(k: number): Matrix4x4 + { + const _local_2 = ((k * Math.PI) / 180); + const _local_3 = Math.cos(_local_2); + const _local_4 = Math.sin(_local_2); + + return new Matrix4x4(1, 0, 0, 0, _local_3, -(_local_4), 0, _local_4, _local_3); + } + + public static _Str_1560(k: number): Matrix4x4 + { + const _local_2 = ((k * Math.PI) / 180); + const _local_3 = Math.cos(_local_2); + const _local_4 = Math.sin(_local_2); + + return new Matrix4x4(_local_3, 0, _local_4, 0, 1, 0, -(_local_4), 0, _local_3); + } + + public static _Str_1368(k: number): Matrix4x4 + { + const _local_2 = ((k * Math.PI) / 180); + const _local_3 = Math.cos(_local_2); + const _local_4 = Math.sin(_local_2); + + return new Matrix4x4(_local_3, -(_local_4), 0, _local_4, _local_3, 0, 0, 0, 1); + } + + public identity(): Matrix4x4 + { + this._data = [1, 0, 0, 0, 1, 0, 0, 0, 1]; + + return this; + } + + public _Str_2186(k: Vector3D): Vector3D + { + const _local_2 = (((k.x * this._data[0]) + (k.y * this._data[3])) + (k.z * this._data[6])); + const _local_3 = (((k.x * this._data[1]) + (k.y * this._data[4])) + (k.z * this._data[7])); + const _local_4 = (((k.x * this._data[2]) + (k.y * this._data[5])) + (k.z * this._data[8])); + + return new Vector3D(_local_2, _local_3, _local_4); + } + + public _Str_1186(k:Matrix4x4): Matrix4x4 + { + const _local_2 = (((this._data[0] * k.data[0]) + (this._data[1] * k.data[3])) + (this._data[2] * k.data[6])); + const _local_3 = (((this._data[0] * k.data[1]) + (this._data[1] * k.data[4])) + (this._data[2] * k.data[7])); + const _local_4 = (((this._data[0] * k.data[2]) + (this._data[1] * k.data[5])) + (this._data[2] * k.data[8])); + const _local_5 = (((this._data[3] * k.data[0]) + (this._data[4] * k.data[3])) + (this._data[5] * k.data[6])); + const _local_6 = (((this._data[3] * k.data[1]) + (this._data[4] * k.data[4])) + (this._data[5] * k.data[7])); + const _local_7 = (((this._data[3] * k.data[2]) + (this._data[4] * k.data[5])) + (this._data[5] * k.data[8])); + const _local_8 = (((this._data[6] * k.data[0]) + (this._data[7] * k.data[3])) + (this._data[8] * k.data[6])); + const _local_9 = (((this._data[6] * k.data[1]) + (this._data[7] * k.data[4])) + (this._data[8] * k.data[7])); + const _local_10 = (((this._data[6] * k.data[2]) + (this._data[7] * k.data[5])) + (this._data[8] * k.data[8])); + + return new Matrix4x4(_local_2, _local_3, _local_4, _local_5, _local_6, _local_7, _local_8, _local_9, _local_10); + } + + public _Str_1157(k: number): void + { + let index = 0; + + while(index < this._data.length) + { + this._data[index] = (this._data[index] * k); + + index++; + } + } + + public _Str_1089(k: number): Matrix4x4 + { + const _local_2 = ((k * Math.PI) / 180); + const _local_3 = Math.cos(_local_2); + const _local_4 = Math.sin(_local_2); + const _local_5 = new Matrix4x4(1, 0, 0, 0, _local_3, -(_local_4), 0, _local_4, _local_3); + + return _local_5._Str_1186(this); + } + + public _Str_2123(k: number): Matrix4x4 + { + const _local_2 = ((k * Math.PI) / 180); + const _local_3 = Math.cos(_local_2); + const _local_4 = Math.sin(_local_2); + const _local_5 = new Matrix4x4(_local_3, 0, _local_4, 0, 1, 0, -(_local_4), 0, _local_3); + + return _local_5._Str_1186(this); + } + + public _Str_2232(k: number): Matrix4x4 + { + const _local_2 = ((k * Math.PI) / 180); + const _local_3 = Math.cos(_local_2); + const _local_4 = Math.sin(_local_2); + const _local_5 = new Matrix4x4(_local_3, -(_local_4), 0, _local_4, _local_3, 0, 0, 0, 1); + + return _local_5._Str_1186(this); + } + + public skew(): void + { + } + + public _Str_1779(): Matrix4x4 + { + return new Matrix4x4(this._data[0], this._data[3], this._data[6], this._data[1], this._data[4], this._data[7], this._data[2], this._data[5], this._data[8]); + } + + public _Str_1451(k: Matrix4x4): boolean + { + return false; + } + + public get data(): number[] + { + return this._data; + } +} \ No newline at end of file diff --git a/src/nitro/avatar/geometry/Node3D.ts b/src/nitro/avatar/geometry/Node3D.ts new file mode 100644 index 00000000..1f52e5ac --- /dev/null +++ b/src/nitro/avatar/geometry/Node3D.ts @@ -0,0 +1,33 @@ +import { Matrix4x4 } from './Matrix4x4'; +import { Vector3D } from './Vector3D'; + +export class Node3D +{ + private _location: Vector3D; + private _transformedLocation: Vector3D; + private _needsTransformation: boolean; + + constructor(k: number, _arg_2: number, _arg_3: number) + { + this._location = new Vector3D(k, _arg_2, _arg_3); + this._transformedLocation = new Vector3D(); + this._needsTransformation = false; + + if(((!(k == 0)) || (!(_arg_2 == 0))) || (!(_arg_3 == 0))) this._needsTransformation = true; + } + + public get location(): Vector3D + { + return this._location; + } + + public get _Str_1604(): Vector3D + { + return this._transformedLocation; + } + + public _Str_1101(k: Matrix4x4): void + { + if(this._needsTransformation) this._transformedLocation = k._Str_2186(this._location); + } +} \ No newline at end of file diff --git a/src/nitro/avatar/geometry/Vector3D.ts b/src/nitro/avatar/geometry/Vector3D.ts new file mode 100644 index 00000000..1f9cfb39 --- /dev/null +++ b/src/nitro/avatar/geometry/Vector3D.ts @@ -0,0 +1,113 @@ +export class Vector3D +{ + private _x: number; + private _y: number; + private _z: number; + + constructor(k: number = 0, _arg_2: number = 0, _arg_3: number = 0) + { + this._x = k; + this._y = _arg_2; + this._z = _arg_3; + } + + public static _Str_2224(k: Vector3D, _arg_2: Vector3D): number + { + return ((k.x * _arg_2.x) + (k.y * _arg_2.y)) + (k.z * _arg_2.z); + } + + public static _Str_1645(k: Vector3D, _arg_2: Vector3D): Vector3D + { + const _local_3 = new Vector3D(); + + _local_3.x = ((k.y * _arg_2.z) - (k.z * _arg_2.y)); + _local_3.y = ((k.z * _arg_2.x) - (k.x * _arg_2.z)); + _local_3.z = ((k.x * _arg_2.y) - (k.y * _arg_2.x)); + + return _local_3; + } + + public static subtract(k: Vector3D, _arg_2: Vector3D): Vector3D + { + return new Vector3D((k.x - _arg_2.x), (k.y - _arg_2.y), (k.z - _arg_2.z)); + } + + public _Str_2224(k: Vector3D): number + { + return ((this._x * k.x) + (this._y * k.y)) + (this._z * k.z); + } + + public _Str_1645(k: Vector3D): Vector3D + { + const _local_2 = new Vector3D(); + + _local_2.x = ((this._y * k.z) - (this._z * k.y)); + _local_2.y = ((this._z * k.x) - (this._x * k.z)); + _local_2.z = ((this._x * k.y) - (this._y * k.x)); + + return _local_2; + } + + public subtract(k: Vector3D): void + { + this._x = (this._x - k.x); + this._y = (this._y - k.y); + this._z = (this._z - k.z); + } + + public add(k: Vector3D): void + { + this._x = (this._x + k.x); + this._y = (this._y + k.y); + this._z = (this._z + k.z); + } + + public normalize(): void + { + const k = (1 / this.length()); + + this._x = (this._x * k); + this._y = (this._y * k); + this._z = (this._z * k); + } + + public length(): number + { + return Math.sqrt((((this._x * this._x) + (this._y * this._y)) + (this._z * this._z))); + } + + public toString(): string + { + return (((((('Vector3D: (' + this._x) + ',') + this._y) + ',') + this._z) + ')'); + } + + public get x(): number + { + return this._x; + } + + public set x(k: number) + { + this._x = k; + } + + public get y(): number + { + return this._y; + } + + public set y(k: number) + { + this._y = k; + } + + public get z(): number + { + return this._z; + } + + public set z(k: number) + { + this._z = k; + } +} \ No newline at end of file diff --git a/src/nitro/avatar/pets/PetCustomPart.ts b/src/nitro/avatar/pets/PetCustomPart.ts new file mode 100644 index 00000000..0c374016 --- /dev/null +++ b/src/nitro/avatar/pets/PetCustomPart.ts @@ -0,0 +1,43 @@ +export class PetCustomPart +{ + private _layerId: number; + private _partId: number; + private _paletteId: number; + + constructor(layerId: number, partId: number, paletteId: number) + { + this._layerId = layerId; + this._partId = partId; + this._paletteId = paletteId; + } + + public get layerId(): number + { + return this._layerId; + } + + public set layerId(layerId: number) + { + this._layerId = layerId; + } + + public get partId(): number + { + return this._partId; + } + + public set partId(partId: number) + { + this._partId = partId; + } + + public get paletteId(): number + { + return this._paletteId; + } + + public set paletteId(paletteId: number) + { + this._paletteId = paletteId; + } +} \ No newline at end of file diff --git a/src/nitro/avatar/pets/PetFigureData.ts b/src/nitro/avatar/pets/PetFigureData.ts new file mode 100644 index 00000000..57a0f102 --- /dev/null +++ b/src/nitro/avatar/pets/PetFigureData.ts @@ -0,0 +1,228 @@ +import { PetCustomPart } from './PetCustomPart'; + +export class PetFigureData +{ + private _typeId: number; + private _paletteId: number; + private _color: number; + private _headOnly: boolean; + + private _customParts: PetCustomPart[]; + private _customLayerIds: number[]; + private _customPartIds: number[]; + private _customPaletteIds: number[]; + + constructor(k: string) + { + this._typeId = this.getTypeId(k); + this._paletteId = this.getPaletteId(k); + this._color = this.getColor(k); + this._headOnly = this.getHeadOnly(k); + + const _local_2 = this.getCustomData(k); + + this._customLayerIds = this.getCustomLayerIds(_local_2); + this._customPartIds = this.getCustomPartIds(_local_2); + this._customPaletteIds = this.getCustomPaletteIds(_local_2); + this._customParts = []; + + let i = 0; + + while(i < this._customLayerIds.length) + { + this._customParts.push(new PetCustomPart(this._customLayerIds[i], this._customPartIds[i], this._customPaletteIds[i])); + + i++; + } + } + + public get typeId(): number + { + return this._typeId; + } + + public get paletteId(): number + { + return this._paletteId; + } + + public get color(): number + { + return this._color; + } + + public get customLayerIds(): number[] + { + return this._customLayerIds; + } + + public get customPartIds(): number[] + { + return this._customPartIds; + } + + public get customPaletteIds(): number[] + { + return this._customPaletteIds; + } + + public get customParts(): PetCustomPart[] + { + return this._customParts; + } + + public getCustomPart(k: number): PetCustomPart + { + if(this._customParts) + { + for(const _local_2 of this._customParts) + { + if(_local_2.layerId === k) return _local_2; + } + } + + return null; + } + + public get hasCustomParts(): boolean + { + return (!(this._customLayerIds == null)) && (this._customLayerIds.length > 0); + } + + public get headOnly(): boolean + { + return this._headOnly; + } + + public get figureString(): string + { + let figure = ((((this.typeId + ' ') + this.paletteId) + ' ') + this.color.toString(16)); + + figure = (figure + (' ' + this.customParts.length)); + + for(const _local_2 of this.customParts) + { + figure = (figure + (((((' ' + _local_2.layerId) + ' ') + _local_2.partId) + ' ') + _local_2.paletteId)); + } + + return figure; + } + + private getCustomData(k: string): string[] + { + let _local_2: string[] = []; + + if(k) + { + const _local_3 = k.split(' '); + const _local_4 = ((this._headOnly) ? 1 : 0); + const _local_5 = (4 + _local_4); + + if(_local_3.length > _local_5) + { + const _local_6 = (3 + _local_4); + const _local_7 = parseInt(_local_3[_local_6]); + + _local_2 = _local_3.slice(_local_5, (_local_5 + (_local_7 * 3))); + } + } + + return _local_2; + } + + private getCustomLayerIds(data: string[]): number[] + { + const layerIds: number[] = []; + + let i = 0; + + while(i < data.length) + { + layerIds.push(parseInt(data[(i + 0)])); + + i = (i + 3); + } + + return layerIds; + } + + private getCustomPartIds(data: string[]): number[] + { + const partIds: number[] = []; + + let i = 0; + + while(i < data.length) + { + partIds.push(parseInt(data[(i + 1)])); + + i = (i + 3); + } + + return partIds; + } + + private getCustomPaletteIds(data: string[]): number[] + { + const paletteIds: number[] = []; + + let i = 0; + + while(i < data.length) + { + paletteIds.push(parseInt(data[(i + 2)])); + + i = (i + 3); + } + + return paletteIds; + } + + private getTypeId(data: string): number + { + if(data) + { + const parts = data.split(' '); + + if(parts.length >= 1) return parseInt(parts[0]); + } + + return 0; + } + + private getPaletteId(data: string): number + { + if(data) + { + const parts = data.split(' '); + + if(parts.length >= 2) return parseInt(parts[1]); + } + + return 0; + } + + private getColor(data: string): number + { + if(data) + { + const parts = data.split(' '); + + if(parts.length >= 3) return parseInt(parts[2], 16); + } + + return 0xFFFFFF; + } + + private getHeadOnly(data: string): boolean + { + if(data) + { + const parts = data.split(' '); + + if(parts.length >= 4) return parts[3] === 'head'; + } + + return false; + } +} \ No newline at end of file diff --git a/src/nitro/avatar/pets/PetType.ts b/src/nitro/avatar/pets/PetType.ts new file mode 100644 index 00000000..cca7168d --- /dev/null +++ b/src/nitro/avatar/pets/PetType.ts @@ -0,0 +1,38 @@ +export class PetType +{ + public static DOG: number = 0; + public static CAT: number = 1; + public static CROCODILE: number = 2; + public static TERRIER: number = 3; + public static BEAR: number = 4; + public static PIG: number = 5; + public static LION: number = 6; + public static RHINO: number = 7; + public static SPIDER: number = 8; + public static TURTLE: number = 9; + public static CHICKEN: number = 10; + public static FROG: number = 11; + public static DRAGON: number = 12; + public static MONSTER: number = 13; + public static MONKEY: number = 14; + public static HORSE: number = 15; + public static MONSTERPLANT: number = 16; + public static BUNNY: number = 17; + public static BUNNYEVIL: number = 18; + public static BUNNYDEPRESSED: number = 19; + public static BUNNYLOVE: number = 20; + public static PIGEONGOOD: number = 21; + public static PIGEONEVIL: number = 22; + public static DEMONMONKEY: number = 23; + public static BABYBEAR: number = 24; + public static BABYTERRIER: number = 25; + public static GNOME: number = 26; + public static LEPRECHAUN: number = 27; + public static KITTENBABY: number = 28; + public static PUPPYBABY: number = 29; + public static PIGLETNBABY: number = 30; + public static HALOOMPA: number = 31; + public static FOOLS: number = 32; + public static PTEROSAUR: number = 33; + public static VELOCIRAPTOR: number = 34; +} \ No newline at end of file diff --git a/src/nitro/avatar/structure/AnimationData.ts b/src/nitro/avatar/structure/AnimationData.ts new file mode 100644 index 00000000..7e714b34 --- /dev/null +++ b/src/nitro/avatar/structure/AnimationData.ts @@ -0,0 +1,58 @@ +import { IActionDefinition } from '../actions/IActionDefinition'; +import { AnimationAction } from './animation/AnimationAction'; +import { IFigureSetData } from './IFigureSetData'; + +export class AnimationData implements IFigureSetData +{ + private _actions: Map; + + constructor() + { + this._actions = new Map(); + } + + public parse(data: any): boolean + { + if(data && (data.length > 0)) + { + for(const animation of data) + { + if(!animation) continue; + + const newAnimation = new AnimationAction(animation); + + this._actions.set(newAnimation.id, newAnimation); + } + } + + return true; + } + + public _Str_1017(k: any): boolean + { + for(const _local_2 of k.action) + { + this._actions.set(_local_2.id, new AnimationAction(_local_2)); + } + + return true; + } + + public _Str_2244(action: IActionDefinition): AnimationAction + { + const existing = this._actions.get(action.id); + + if(!existing) return null; + + return existing; + } + + public _Str_1408(k: IActionDefinition): number + { + const animationAction = this._Str_2244(k); + + if(!animationAction) return 0; + + return animationAction._Str_2185; + } +} \ No newline at end of file diff --git a/src/nitro/avatar/structure/AvatarCanvas.ts b/src/nitro/avatar/structure/AvatarCanvas.ts new file mode 100644 index 00000000..b47a79e9 --- /dev/null +++ b/src/nitro/avatar/structure/AvatarCanvas.ts @@ -0,0 +1,47 @@ +import { Point } from 'pixi.js'; +import { AvatarScaleType } from '../enum/AvatarScaleType'; + +export class AvatarCanvas +{ + private _id: string; + private _width: number; + private _height: number; + private _offset: Point; + private _regPoint: Point; + + constructor(k: any, _arg_2: string) + { + this._id = k.id; + this._width = k.width; + this._height = k.height; + this._offset = new Point(k.dx, k.dy); + + if(_arg_2 == AvatarScaleType.LARGE) this._regPoint = new Point(((this._width - 64) / 2), 0); + else this._regPoint = new Point(((this._width - 32) / 2), 0); + } + + public get width(): number + { + return this._width; + } + + public get height(): number + { + return this._height; + } + + public get offset(): Point + { + return this._offset; + } + + public get id(): string + { + return this._id; + } + + public get _Str_1076(): Point + { + return this._regPoint; + } +} \ No newline at end of file diff --git a/src/nitro/avatar/structure/AvatarStructureDownload.ts b/src/nitro/avatar/structure/AvatarStructureDownload.ts new file mode 100644 index 00000000..215c0597 --- /dev/null +++ b/src/nitro/avatar/structure/AvatarStructureDownload.ts @@ -0,0 +1,57 @@ +import { Parser } from 'xml2js'; +import { NitroLogger } from '../../../core/common/logger/NitroLogger'; +import { EventDispatcher } from '../../../core/events/EventDispatcher'; +import { NitroEvent } from '../../../core/events/NitroEvent'; +import { IFigureSetData } from './IFigureSetData'; + +export class AvatarStructureDownload extends EventDispatcher +{ + public static AVATAR_STRUCTURE_DONE: string = 'AVATAR_STRUCTURE_DONE'; + + private _dataReceiver: IFigureSetData; + + constructor(downloadUrl: string, dataReceiver: IFigureSetData) + { + super(); + + this._dataReceiver = dataReceiver; + + this.download(downloadUrl); + } + + private download(url: string): void + { + const request = new XMLHttpRequest(); + + try + { + request.open('GET', url); + + request.send(); + + request.onloadend = e => + { + const parser = new Parser(); + + parser.parseString(request.responseText, (err: Error, results: any) => + { + if(err || !results || !results.figuredata) throw new Error('invalid_figure_data'); + + if(this._dataReceiver) this._dataReceiver._Str_1017(results.figuredata); + + this.dispatchEvent(new NitroEvent(AvatarStructureDownload.AVATAR_STRUCTURE_DONE)); + }); + }; + + request.onerror = e => + { + throw new Error('invalid_avatar_figure_data'); + }; + } + + catch (e) + { + NitroLogger.log(e); + } + } +} \ No newline at end of file diff --git a/src/nitro/avatar/structure/FigureSetData.ts b/src/nitro/avatar/structure/FigureSetData.ts new file mode 100644 index 00000000..6a40a993 --- /dev/null +++ b/src/nitro/avatar/structure/FigureSetData.ts @@ -0,0 +1,152 @@ +import { IFigurePartSet } from './figure/IFigurePartSet'; +import { IPalette } from './figure/IPalette'; +import { ISetType } from './figure/ISetType'; +import { Palette } from './figure/Palette'; +import { SetType } from './figure/SetType'; +import { IFigureSetData } from './IFigureSetData'; +import { IStructureData } from './IStructureData'; + +export class FigureSetData implements IFigureSetData, IStructureData +{ + private _palettes: Map; + private _setTypes: Map; + + constructor() + { + this._palettes = new Map(); + this._setTypes = new Map(); + } + + public dispose(): void + { + + } + + public parse(data: any): boolean + { + if(!data) return false; + + for(const palette of data.colors[0].palette) + { + const newPalette = new Palette(palette); + + if(!newPalette) continue; + + this._palettes.set(newPalette.id.toString(), newPalette); + } + + for(const set of data.sets[0].settype) + { + const newSet = new SetType(set); + + if(!newSet) continue; + + this._setTypes.set(newSet.type, newSet); + } + + return true; + } + + public _Str_1133(k: any): void + { + for(const _local_2 of k.sets[0].settype) + { + const setType = this._setTypes.get(_local_2['$'].type); + + if(setType) + { + setType._Str_1874(_local_2); + } + else + { + this._setTypes.set(_local_2['$'].type, new SetType(_local_2)); + } + } + + this._Str_1017(k); + } + + public _Str_1017(k: any): boolean + { + if(!k) return false; + + for(const _local_2 of k.colors[0].palette) + { + const id = _local_2['$'].id.toString(); + const _local_4 = this._palettes.get(id); + + if(!_local_4) + { + this._palettes.set(id, new Palette(_local_2)); + } + else + { + _local_4._Str_2015(_local_2); + } + } + + for(const _local_3 of k.sets[0].settype) + { + const type = _local_3['$'].type; + const _local_5 = this._setTypes.get(type); + + if(!_local_5) + { + this._setTypes.set(type, new SetType(_local_3)); + } + else + { + _local_5._Str_2015(_local_3); + } + } + + return false; + } + + public _Str_1733(k: string, _arg_2: number): string[] + { + const types: string[] = []; + + for(const set of this._setTypes.values()) + { + if(!set || !set._Str_895(k, _arg_2)) continue; + + types.push(set.type); + } + + return types; + } + + public _Str_2264(k: string, _arg_2: string): IFigurePartSet + { + const setType = this._setTypes.get(k); + + if(!setType) return null; + + return setType._Str_2264(_arg_2); + } + + public _Str_740(k: string): ISetType + { + return (this._setTypes.get(k) || null); + } + + public _Str_783(k: number): IPalette + { + return (this._palettes.get(k.toString()) || null); + } + + public _Str_938(k: number): IFigurePartSet + { + for(const set of this._setTypes.values()) + { + const partSet = set._Str_1020(k); + + if(!partSet) continue; + + return partSet; + } + + return null; + } +} \ No newline at end of file diff --git a/src/nitro/avatar/structure/IFigureSetData.ts b/src/nitro/avatar/structure/IFigureSetData.ts new file mode 100644 index 00000000..444911f3 --- /dev/null +++ b/src/nitro/avatar/structure/IFigureSetData.ts @@ -0,0 +1,5 @@ +export interface IFigureSetData +{ + parse(data: any): boolean; + _Str_1017(data: any): boolean; +} \ No newline at end of file diff --git a/src/nitro/avatar/structure/IStructureData.ts b/src/nitro/avatar/structure/IStructureData.ts new file mode 100644 index 00000000..05dac860 --- /dev/null +++ b/src/nitro/avatar/structure/IStructureData.ts @@ -0,0 +1,12 @@ +import { IFigurePartSet } from './figure/IFigurePartSet'; +import { IPalette } from './figure/IPalette'; +import { ISetType } from './figure/ISetType'; + +export interface IStructureData +{ + parse(data: any): boolean; + _Str_1017(k: any): boolean; + _Str_740(_arg_1: string): ISetType; + _Str_783(_arg_1: number): IPalette; + _Str_938(_arg_1: number): IFigurePartSet; +} \ No newline at end of file diff --git a/src/nitro/avatar/structure/PartSetsData.ts b/src/nitro/avatar/structure/PartSetsData.ts new file mode 100644 index 00000000..99236c7a --- /dev/null +++ b/src/nitro/avatar/structure/PartSetsData.ts @@ -0,0 +1,120 @@ +import { ActionDefinition } from '../actions/ActionDefinition'; +import { IActionDefinition } from '../actions/IActionDefinition'; +import { IFigureSetData } from './IFigureSetData'; +import { ActivePartSet } from './parts/ActivePartSet'; +import { PartDefinition } from './parts/PartDefinition'; + +export class PartSetsData implements IFigureSetData +{ + private _parts: Map; + private _activePartSets: Map; + + constructor() + { + this._parts = new Map(); + this._activePartSets = new Map(); + } + + public parse(data: any): boolean + { + if(data.partSet && (data.partSet.length > 0)) + { + for(const part of data.partSet) + { + if(!part) continue; + + this._parts.set(part.setType, new PartDefinition(part)); + } + } + + if(data.activePartSets && (data.activePartSets.length > 0)) + { + for(const activePart of data.activePartSets) + { + if(!activePart) continue; + + this._activePartSets.set(activePart.id, new ActivePartSet(activePart)); + } + } + + return true; + } + + public _Str_1017(data: any): boolean + { + if(data.partSet && (data.partSet.length > 0)) + { + for(const part of data.partSet) + { + if(!part) continue; + + this._parts.set(part.setType, new PartDefinition(part)); + } + } + + if(data.activePartSets && (data.activePartSets.length > 0)) + { + for(const activePart of data.activePartSets) + { + if(!activePart) continue; + + this._activePartSets.set(activePart.id, new ActivePartSet(activePart)); + } + } + + return false; + } + + public _Str_1795(k:IActionDefinition): string[] + { + const activePartSet = this._activePartSets.get(k.activePartSet); + + if(!activePartSet) return []; + + return activePartSet._Str_806; + } + + public _Str_1102(part: string): PartDefinition + { + const existing = this._parts.get(part); + + if(!existing) return null; + + return existing; + } + + public _Str_1520(k: any): PartDefinition + { + const _local_2 = k.setType as string; + + let existing = this._parts.get(_local_2); + + if(!existing) + { + existing = new PartDefinition(k); + + this._parts.set(_local_2, existing); + } + + return existing; + } + + public _Str_1113(k: ActionDefinition): ActivePartSet + { + const existing = this._activePartSets.get(k.activePartSet); + + if(!existing) return null; + + return existing; + } + + public get _Str_806(): Map + { + return this._parts; + } + + public get _Str_1979(): Map + { + return this._activePartSets; + } +} \ No newline at end of file diff --git a/src/nitro/avatar/structure/animation/AnimationAction.ts b/src/nitro/avatar/structure/animation/AnimationAction.ts new file mode 100644 index 00000000..462d54a2 --- /dev/null +++ b/src/nitro/avatar/structure/animation/AnimationAction.ts @@ -0,0 +1,138 @@ +import { Point } from 'pixi.js'; +import { AnimationActionPart } from './AnimationActionPart'; + +export class AnimationAction +{ + public static _Str_1934: Point = new Point(0, 0); + + private _id: string; + private _actionParts: Map; + private _bodyPartOffsets: Map>>; + private _frameCount: number; + private _frameIndexes: number[]; + + constructor(data: any) + { + this._id = data.id; + this._actionParts = new Map(); + this._bodyPartOffsets = new Map(); + this._frameCount = 0; + this._frameIndexes = []; + + if(data.parts && (data.parts.length > 0)) + { + for(const part of data.parts) + { + if(!part) continue; + + const newPart = new AnimationActionPart(part); + + this._actionParts.set(part.setType, newPart); + + this._frameCount = Math.max(this._frameCount, newPart.frames.length); + } + } + + if(data.offsets && data.offsets.frames && (data.offsets.frames.length > 0)) + { + for(const frame of data.offsets.frames) + { + if(!frame) continue; + + const frameId = frame.id; + + this._frameCount = Math.max(this._frameCount, frameId); + + const directions: Map> = new Map(); + + this._bodyPartOffsets.set(frameId, directions); + + if(frame.directions && (frame.directions.length > 0)) + { + for(const direction of frame.directions) + { + if(!direction) continue; + + const directionId = direction.id; + + const offsets: Map = new Map(); + + directions.set(directionId, offsets); + + if(direction.bodyParts && (direction.bodyParts.length > 0)) + { + for(const part of direction.bodyParts) + { + if(!part) continue; + + const partId = part.id; + + let dx = 0; + let dy = 0; + + if(part.dx !== undefined) dx = part.dx; + if(part.dy !== undefined) dy = part.dy; + + offsets.set(partId, new Point(dx, dy)); + } + } + } + } + + this._frameIndexes.push(frameId); + + if(frame.repeats !== undefined) + { + let repeats = frame.repeats || 0; + + if(repeats > 1) while(--repeats > 0) this._frameIndexes.push(frameId); + } + } + } + } + + public _Str_989(type: string): AnimationActionPart + { + if(!type) return null; + + const existing = this._actionParts.get(type); + + if(!existing) return null; + + return existing; + } + + public _Str_1888(frameId: number, frameCount: number, partId: string): Point + { + const frameIndex = (frameCount % this._frameIndexes.length); + const frameNumber = this._frameIndexes[frameIndex]; + const offsets = this._bodyPartOffsets.get(frameNumber); + + if(!offsets) return AnimationAction._Str_1934; + + const frameOffset = offsets.get(frameId); + + if(!frameOffset) return AnimationAction._Str_1934; + + const offset = frameOffset.get(partId); + + if(!offset) return AnimationAction._Str_1934; + + return offset; + } + + public get id(): string + { + return this._id; + } + + public get _Str_806(): Map + { + return this._actionParts; + } + + public get _Str_2185(): number + { + return this._frameCount; + } +} \ No newline at end of file diff --git a/src/nitro/avatar/structure/animation/AnimationActionPart.ts b/src/nitro/avatar/structure/animation/AnimationActionPart.ts new file mode 100644 index 00000000..6df6b5db --- /dev/null +++ b/src/nitro/avatar/structure/animation/AnimationActionPart.ts @@ -0,0 +1,30 @@ +import { AnimationFrame } from './AnimationFrame'; + +export class AnimationActionPart +{ + private _frames: AnimationFrame[]; + + constructor(data: any) + { + this._frames = []; + + if(data.frames && (data.frames.length > 0)) + { + for(const frame of data.frames) + { + if(!frame) continue; + + this._frames.push(new AnimationFrame(frame)); + + let repeats = frame.repeats || 0; + + if(repeats > 1) while(--repeats > 0) this._frames.push(this._frames[(this._frames.length - 1)]); + } + } + } + + public get frames(): AnimationFrame[] + { + return this._frames; + } +} \ No newline at end of file diff --git a/src/nitro/avatar/structure/animation/AnimationFrame.ts b/src/nitro/avatar/structure/animation/AnimationFrame.ts new file mode 100644 index 00000000..74899f9c --- /dev/null +++ b/src/nitro/avatar/structure/animation/AnimationFrame.ts @@ -0,0 +1,21 @@ +export class AnimationFrame +{ + private _number: number; + private _assetPartDefinition: string; + + constructor(data: any) + { + this._number = data.number; + this._assetPartDefinition = data.assetPartDefinition || null; + } + + public get number(): number + { + return this._number; + } + + public get _Str_778(): string + { + return this._assetPartDefinition; + } +} \ No newline at end of file diff --git a/src/nitro/avatar/structure/figure/FigurePart.ts b/src/nitro/avatar/structure/figure/FigurePart.ts new file mode 100644 index 00000000..93455739 --- /dev/null +++ b/src/nitro/avatar/structure/figure/FigurePart.ts @@ -0,0 +1,66 @@ +import { IFigurePart } from './IFigurePart'; + +export class FigurePart implements IFigurePart +{ + private _id: number; + private _type: string; + private _breed: number; + private _index: number; + private _colorLayerIndex: number; + private _paletteMapId: number; + + constructor(data: any) + { + if(!data) throw new Error('invalid_data'); + + this._id = parseInt(data['$'].id); + this._type = data['$'].type; + this._index = parseInt(data['$'].index); + this._colorLayerIndex = parseInt(data['$'].colorindex); + + const paletteMapId = data['$'].palettemapid; + + if(!isNaN(paletteMapId)) this._paletteMapId = parseInt(paletteMapId); + else this._paletteMapId = -1; + + const breed = data['$'].palettemapid; + + if(!isNaN(breed)) this._breed = parseInt(breed); + else this._breed = -1; + } + + public dispose(): void + { + + } + + public get id(): number + { + return this._id; + } + + public get type(): string + { + return this._type; + } + + public get breed(): number + { + return this._breed; + } + + public get index(): number + { + return this._index; + } + + public get _Str_827(): number + { + return this._colorLayerIndex; + } + + public get paletteMap(): number + { + return this._paletteMapId; + } +} \ No newline at end of file diff --git a/src/nitro/avatar/structure/figure/FigurePartSet.ts b/src/nitro/avatar/structure/figure/FigurePartSet.ts new file mode 100644 index 00000000..6d9163e8 --- /dev/null +++ b/src/nitro/avatar/structure/figure/FigurePartSet.ts @@ -0,0 +1,144 @@ +import { FigurePart } from './FigurePart'; +import { IFigurePart } from './IFigurePart'; +import { IFigurePartSet } from './IFigurePartSet'; + +export class FigurePartSet implements IFigurePartSet +{ + private _id: number; + private _type: string; + private _gender: string; + private _clubLevel: number; + private _isColorable: boolean; + private _isSelectable: boolean; + private _parts: IFigurePart[]; + private _hiddenLayers: string[]; + private _isPreSelectable: boolean; + private _isSellable: boolean; + + constructor(type: string, data: any) + { + if(!type || !data) throw new Error('invalid_data'); + + this._id = parseInt(data['$'].id); + this._type = type; + this._gender = data['$'].gender; + this._clubLevel = parseInt(data['$'].club); + this._isColorable = parseInt(data['$'].colorable) === 1; + this._isSelectable = parseInt(data['$'].selectable) === 1; + this._parts = []; + this._hiddenLayers = []; + this._isPreSelectable = parseInt(data['$'].preselectable) === 1; + this._isSellable = parseInt(data['$'].sellable) === 1; + + for(const part of data.part) + { + const newPart = new FigurePart(part); + const partIndex = this.getPartIndex(newPart); + + if(partIndex !== -1) this._parts.splice(partIndex, 0, newPart); + else this._parts.push(newPart); + } + + if(data.hiddenlayers) + { + const hiddenLayers = data.hiddenlayers[0]; + + for(const layer of hiddenLayers.layer) this._hiddenLayers.push(layer['$'].parttype); + } + } + + public dispose(): void + { + for(const part of this._parts) + { + const figurePart = part as FigurePart; + + figurePart.dispose(); + } + + this._parts = null; + this._hiddenLayers = null; + } + + private getPartIndex(part: FigurePart): number + { + const totalParts = this._parts.length; + + if(!totalParts) return -1; + + for(let i = 0; i < totalParts; i++) + { + const existingPart = this._parts[i]; + + if(!existingPart) continue; + + if(existingPart.type !== part.type || existingPart.index > part.index) continue; + + return i; + } + + return -1; + } + + public _Str_989(k: string, _arg_2: number): IFigurePart + { + for(const part of this._parts) + { + if((part.type !== k) || (part.id !== _arg_2)) continue; + + return part; + } + + return null; + } + + public get id(): number + { + return this._id; + } + + public get type(): string + { + return this._type; + } + + public get gender(): string + { + return this._gender; + } + + public get clubLevel(): number + { + return this._clubLevel; + } + + public get isColorable(): boolean + { + return this._isColorable; + } + + public get _Str_608(): boolean + { + return this._isSelectable; + } + + public get _Str_806(): IFigurePart[] + { + return this._parts; + } + + public get _Str_790(): string[] + { + return this._hiddenLayers; + } + + public get _Str_653(): boolean + { + return this._isPreSelectable; + } + + public get _Str_651(): boolean + { + return this._isSellable; + } +} \ No newline at end of file diff --git a/src/nitro/avatar/structure/figure/IFigurePart.ts b/src/nitro/avatar/structure/figure/IFigurePart.ts new file mode 100644 index 00000000..882e178f --- /dev/null +++ b/src/nitro/avatar/structure/figure/IFigurePart.ts @@ -0,0 +1,9 @@ +export interface IFigurePart +{ + id: number; + type: string; + breed: number; + index: number; + _Str_827: number; + paletteMap: number; +} \ No newline at end of file diff --git a/src/nitro/avatar/structure/figure/IFigurePartSet.ts b/src/nitro/avatar/structure/figure/IFigurePartSet.ts new file mode 100644 index 00000000..1b08de5d --- /dev/null +++ b/src/nitro/avatar/structure/figure/IFigurePartSet.ts @@ -0,0 +1,16 @@ +import { IFigurePart } from './IFigurePart'; + +export interface IFigurePartSet +{ + _Str_989(_arg_1: string, _arg_2: number): IFigurePart; + id: number; + type: string; + gender: string; + clubLevel: number; + isColorable: boolean; + _Str_608: boolean; + _Str_806: IFigurePart[]; + _Str_790: string[]; + _Str_653: boolean; + _Str_651: boolean; +} \ No newline at end of file diff --git a/src/nitro/avatar/structure/figure/IPalette.ts b/src/nitro/avatar/structure/figure/IPalette.ts new file mode 100644 index 00000000..dd5233e7 --- /dev/null +++ b/src/nitro/avatar/structure/figure/IPalette.ts @@ -0,0 +1,8 @@ +import { IPartColor } from './IPartColor'; + +export interface IPalette +{ + _Str_751(id: number): IPartColor; + id: number; + colors: Map; +} \ No newline at end of file diff --git a/src/nitro/avatar/structure/figure/IPartColor.ts b/src/nitro/avatar/structure/figure/IPartColor.ts new file mode 100644 index 00000000..2630b71f --- /dev/null +++ b/src/nitro/avatar/structure/figure/IPartColor.ts @@ -0,0 +1,8 @@ +export interface IPartColor +{ + id: number; + index: number; + clubLevel: number; + isSelectable: boolean; + _Str_915: number; +} \ No newline at end of file diff --git a/src/nitro/avatar/structure/figure/ISetType.ts b/src/nitro/avatar/structure/figure/ISetType.ts new file mode 100644 index 00000000..29f2c5dd --- /dev/null +++ b/src/nitro/avatar/structure/figure/ISetType.ts @@ -0,0 +1,12 @@ +import { AdvancedMap } from '../../../../core/utils/AdvancedMap'; +import { IFigurePartSet } from './IFigurePartSet'; + +export interface ISetType +{ + _Str_1020(_arg_1: number): IFigurePartSet; + _Str_895(_arg_1: string, _arg_2: number): boolean; + _Str_1002(_arg_1: string): number; + type: string; + _Str_734: number; + _Str_710: AdvancedMap; +} \ No newline at end of file diff --git a/src/nitro/avatar/structure/figure/Palette.ts b/src/nitro/avatar/structure/figure/Palette.ts new file mode 100644 index 00000000..5e15d1f2 --- /dev/null +++ b/src/nitro/avatar/structure/figure/Palette.ts @@ -0,0 +1,46 @@ +import { IPalette } from './IPalette'; +import { IPartColor } from './IPartColor'; +import { PartColor } from './PartColor'; + +export class Palette implements IPalette +{ + private _id: number; + private _colors: Map; + + constructor(data: any) + { + if(!data) throw new Error('invalid_data'); + + this._id = parseInt(data['$'].id); + this._colors = new Map(); + + this._Str_2015(data); + } + + public _Str_2015(data: any): void + { + for(const color of data.color) + { + const newColor = new PartColor(color); + + this._colors.set(color['$'].id.toString(), newColor); + } + } + + public _Str_751(id: number): IPartColor + { + if((id === undefined) || id < 0) return null; + + return (this._colors.get(id.toString()) || null); + } + + public get id(): number + { + return this._id; + } + + public get colors(): Map + { + return this._colors; + } +} \ No newline at end of file diff --git a/src/nitro/avatar/structure/figure/PartColor.ts b/src/nitro/avatar/structure/figure/PartColor.ts new file mode 100644 index 00000000..24c34367 --- /dev/null +++ b/src/nitro/avatar/structure/figure/PartColor.ts @@ -0,0 +1,46 @@ +import { IPartColor } from './IPartColor'; + +export class PartColor implements IPartColor +{ + private _id: number; + private _index: number; + private _clubLevel: number; + private _isSelectable: boolean; + private _rgb: number; + + constructor(data: any) + { + if(!data) throw new Error('invalid_data'); + + this._id = parseInt(data['$'].id); + this._index = parseInt(data['$'].index); + this._clubLevel = parseInt(data['$'].club); + this._isSelectable = parseInt(data['$'].selectable) === 1; + this._rgb = parseInt('0x' + data['_'], 16); + } + + public get id(): number + { + return this._id; + } + + public get index(): number + { + return this._index; + } + + public get clubLevel(): number + { + return this._clubLevel; + } + + public get isSelectable(): boolean + { + return this._isSelectable; + } + + public get _Str_915(): number + { + return this._rgb; + } +} \ No newline at end of file diff --git a/src/nitro/avatar/structure/figure/SetType.ts b/src/nitro/avatar/structure/figure/SetType.ts new file mode 100644 index 00000000..618cb143 --- /dev/null +++ b/src/nitro/avatar/structure/figure/SetType.ts @@ -0,0 +1,105 @@ +import { AdvancedMap } from '../../../../core/utils/AdvancedMap'; +import { FigurePartSet } from './FigurePartSet'; +import { IFigurePartSet } from './IFigurePartSet'; +import { ISetType } from './ISetType'; + +export class SetType implements ISetType +{ + private _type: string; + private _paletteId: number; + private _isMandatory: { [index: string]: boolean[] }; + private _partSets: AdvancedMap; + + constructor(data: any) + { + if(!data) throw new Error('invalid_data'); + + this._type = data['$'].type; + this._paletteId = parseInt(data['$'].paletteid); + this._isMandatory = {}; + this._isMandatory['F'] = [ parseInt(data['$'].mand_f_0) === 1, parseInt(data['$'].mand_f_1) === 1 ]; + this._isMandatory['M'] = [ (parseInt(data['$'].mand_m_0) === 1), (parseInt(data['$'].mand_m_1) === 1) ]; + this._partSets = new AdvancedMap(); + + this._Str_2015(data); + } + + public dispose(): void + { + for(const set of this._partSets.getValues()) + { + const partSet = set as FigurePartSet; + + partSet.dispose(); + } + + this._partSets = null; + } + + public _Str_1874(k: any): void + { + for(const _local_2 of k) + { + const _local_3 = (_local_2.id as string); + const _local_4 = (this._partSets.getValue(_local_3) as FigurePartSet); + + if(_local_4) + { + _local_4.dispose(); + + this._partSets.remove(_local_3); + } + } + } + + public _Str_2015(k: any): void + { + if(!k || !k.set) return; + + for(const set of k.set) this._partSets.add(set['$'].id, new FigurePartSet(this._type, set)); + } + + public _Str_2264(k: string): IFigurePartSet + { + for(const set of this._partSets.getValues()) + { + if(!set) continue; + + if((set.clubLevel === 0) && ((set.gender === k) || (set.gender === 'U'))) return set; + } + + return null; + } + + public _Str_1020(k: number): IFigurePartSet + { + return this._partSets.getValue(k.toString()); + } + + public get type(): string + { + return this._type; + } + + public get _Str_734(): number + { + return this._paletteId; + } + + public _Str_895(k: string, _arg_2: number): boolean + { + return this._isMandatory[k.toUpperCase()][Math.min(_arg_2, 1)]; + } + + public _Str_1002(k: string): number + { + const _local_2 = this._isMandatory[k.toUpperCase()]; + + return _local_2.indexOf(false); + } + + public get _Str_710(): AdvancedMap + { + return this._partSets; + } +} \ No newline at end of file diff --git a/src/nitro/avatar/structure/parts/ActivePartSet.ts b/src/nitro/avatar/structure/parts/ActivePartSet.ts new file mode 100644 index 00000000..9e3ac69d --- /dev/null +++ b/src/nitro/avatar/structure/parts/ActivePartSet.ts @@ -0,0 +1,26 @@ +export class ActivePartSet +{ + private _id: string; + private _parts: string[]; + + constructor(data: any) + { + this._id = data.id; + this._parts = []; + + if(data.activeParts && (data.activeParts.length > 0)) + { + for(const part of data.activeParts) + { + if(!part) continue; + + this._parts.push(part.setType); + } + } + } + + public get _Str_806(): string[] + { + return this._parts; + } +} \ No newline at end of file diff --git a/src/nitro/avatar/structure/parts/PartDefinition.ts b/src/nitro/avatar/structure/parts/PartDefinition.ts new file mode 100644 index 00000000..305ce47b --- /dev/null +++ b/src/nitro/avatar/structure/parts/PartDefinition.ts @@ -0,0 +1,64 @@ +export class PartDefinition +{ + private _setType: string; + private _flippedSetType: string; + private _removeSetType: string; + private _appendToFigure: boolean; + private _staticId: number; + + constructor(data: any) + { + if(!data) throw new Error('invalid_data'); + + this._setType = data.setType; + this._flippedSetType = data.flippedSetType || null; + this._removeSetType = data.removeSetType || null; + this._appendToFigure = false; + this._staticId = -1; + } + + public _Str_2234(): boolean + { + return this._staticId >= 0; + } + + public get _Str_1734(): number + { + return this._staticId; + } + + public set _Str_1734(k: number) + { + this._staticId = k; + } + + public get _Str_2174(): string + { + return this._setType; + } + + public get _Str_1693(): string + { + return this._flippedSetType; + } + + public set _Str_1693(type: string) + { + this._flippedSetType = type; + } + + public get _Str_1209(): string + { + return this._removeSetType; + } + + public get _Str_1583(): boolean + { + return this._appendToFigure; + } + + public set _Str_1583(flag: boolean) + { + this._appendToFigure = flag; + } +} \ No newline at end of file diff --git a/src/nitro/communication/INitroCommunicationManager.ts b/src/nitro/communication/INitroCommunicationManager.ts new file mode 100644 index 00000000..39041234 --- /dev/null +++ b/src/nitro/communication/INitroCommunicationManager.ts @@ -0,0 +1,12 @@ +import { INitroManager } from '../../core/common/INitroManager'; +import { IConnection } from '../../core/communication/connections/IConnection'; +import { IMessageEvent } from '../../core/communication/messages/IMessageEvent'; +import { NitroCommunicationDemo } from './demo/NitroCommunicationDemo'; + +export interface INitroCommunicationManager extends INitroManager +{ + registerMessageEvent(event: IMessageEvent): IMessageEvent; + removeMessageEvent(event: IMessageEvent): void; + demo: NitroCommunicationDemo; + connection: IConnection; +} \ No newline at end of file diff --git a/src/nitro/communication/NitroCommunicationManager.ts b/src/nitro/communication/NitroCommunicationManager.ts new file mode 100644 index 00000000..cccae233 --- /dev/null +++ b/src/nitro/communication/NitroCommunicationManager.ts @@ -0,0 +1,124 @@ +import { NitroManager } from '../../core/common/NitroManager'; +import { IConnection } from '../../core/communication/connections/IConnection'; +import { IConnectionStateListener } from '../../core/communication/connections/IConnectionStateListener'; +import { SocketConnectionEvent } from '../../core/communication/events/SocketConnectionEvent'; +import { ICommunicationManager } from '../../core/communication/ICommunicationManager'; +import { IMessageConfiguration } from '../../core/communication/messages/IMessageConfiguration'; +import { IMessageEvent } from '../../core/communication/messages/IMessageEvent'; +import { NitroEvent } from '../../core/events/NitroEvent'; +import { Nitro } from '../Nitro'; +import { NitroCommunicationDemo } from './demo/NitroCommunicationDemo'; +import { NitroCommunicationDemoEvent } from './demo/NitroCommunicationDemoEvent'; +import { INitroCommunicationManager } from './INitroCommunicationManager'; +import { NitroMessages } from './NitroMessages'; + +export class NitroCommunicationManager extends NitroManager implements INitroCommunicationManager, IConnectionStateListener +{ + private _communication: ICommunicationManager; + private _connection: IConnection; + private _messages: IMessageConfiguration; + + private _demo: NitroCommunicationDemo; + + constructor(communication: ICommunicationManager) + { + super(); + + this._communication = communication; + this._connection = null; + this._messages = new NitroMessages(); + + this._demo = new NitroCommunicationDemo(this); + + this.onConnectionOpenedEvent = this.onConnectionOpenedEvent.bind(this); + this.onConnectionClosedEvent = this.onConnectionClosedEvent.bind(this); + this.onConnectionErrorEvent = this.onConnectionErrorEvent.bind(this); + this.onConnectionAuthenticatedEvent = this.onConnectionAuthenticatedEvent.bind(this); + } + + protected onInit(): void + { + if(this._connection) return; + + Nitro.instance.events.addEventListener(NitroCommunicationDemoEvent.CONNECTION_AUTHENTICATED, this.onConnectionAuthenticatedEvent); + + this._connection = this._communication.createConnection(this); + + this._connection.registerMessages(this._messages); + + this._connection.addEventListener(SocketConnectionEvent.CONNECTION_OPENED, this.onConnectionOpenedEvent); + this._connection.addEventListener(SocketConnectionEvent.CONNECTION_CLOSED, this.onConnectionClosedEvent); + this._connection.addEventListener(SocketConnectionEvent.CONNECTION_ERROR, this.onConnectionErrorEvent); + + if(this._demo) this._demo.init(); + + this._connection.init(Nitro.instance.getConfiguration('socket.url')); + } + + protected onDispose(): void + { + if(this._demo) this._demo.dispose(); + + if(this._connection) + { + this._connection.removeEventListener(SocketConnectionEvent.CONNECTION_OPENED, this.onConnectionOpenedEvent); + this._connection.removeEventListener(SocketConnectionEvent.CONNECTION_CLOSED, this.onConnectionClosedEvent); + this._connection.removeEventListener(SocketConnectionEvent.CONNECTION_ERROR, this.onConnectionErrorEvent); + } + + Nitro.instance.events.removeEventListener(NitroCommunicationDemoEvent.CONNECTION_AUTHENTICATED, this.onConnectionAuthenticatedEvent); + + super.onDispose(); + } + + private onConnectionOpenedEvent(event: Event): void + { + this.logger.log('Connection Initialized'); + } + + private onConnectionClosedEvent(event: CloseEvent): void + { + this.logger.log('Connection Closed'); + } + + private onConnectionErrorEvent(event: Event): void + { + this.logger.log('Connection Error'); + } + + private onConnectionAuthenticatedEvent(event: NitroEvent): void + { + this.logger.log('Connection Authenticated'); + + if(this._connection) this._connection.authenticated(); + } + + public connectionInit(socketUrl: string): void + { + this.logger.log(`Initializing Connection: ${ socketUrl }`); + } + + public registerMessageEvent(event: IMessageEvent): IMessageEvent + { + if(this._connection) this._connection.addMessageEvent(event); + + return event; + } + + public removeMessageEvent(event: IMessageEvent): void + { + if(!this._connection) return; + + this._connection.removeMessageEvent(event); + } + + public get demo(): NitroCommunicationDemo + { + return this._demo; + } + + public get connection(): IConnection + { + return this._connection; + } +} diff --git a/src/nitro/communication/NitroMessages.ts b/src/nitro/communication/NitroMessages.ts new file mode 100644 index 00000000..744024b9 --- /dev/null +++ b/src/nitro/communication/NitroMessages.ts @@ -0,0 +1,971 @@ +import { IMessageConfiguration } from '../../core/communication/messages/IMessageConfiguration'; +import { AvailabilityStatusMessageEvent } from './messages/incoming/availability/AvailabilityStatusMessageEvent'; +import { ChangeNameUpdateEvent } from './messages/incoming/avatar/ChangeNameUpdateEvent'; +import { CatalogClubEvent } from './messages/incoming/catalog/CatalogClubEvent'; +import { CatalogClubGiftsEvent } from './messages/incoming/catalog/CatalogClubGiftsEvent'; +import { CatalogGiftConfigurationEvent } from './messages/incoming/catalog/CatalogGiftConfigurationEvent'; +import { CatalogGiftUsernameUnavailableEvent } from './messages/incoming/catalog/CatalogGiftUsernameUnavailableEvent'; +import { CatalogGroupsEvent } from './messages/incoming/catalog/CatalogGroupsEvent'; +import { CatalogModeEvent } from './messages/incoming/catalog/CatalogModeEvent'; +import { CatalogPageEvent } from './messages/incoming/catalog/CatalogPageEvent'; +import { CatalogPagesEvent } from './messages/incoming/catalog/CatalogPagesEvent'; +import { CatalogPurchaseEvent } from './messages/incoming/catalog/CatalogPurchaseEvent'; +import { CatalogPurchaseFailedEvent } from './messages/incoming/catalog/CatalogPurchaseFailedEvent'; +import { CatalogPurchaseUnavailableEvent } from './messages/incoming/catalog/CatalogPurchaseUnavailableEvent'; +import { CatalogRedeemVoucherErrorEvent } from './messages/incoming/catalog/CatalogRedeemVoucherErrorEvent'; +import { CatalogRedeemVoucherOkEvent } from './messages/incoming/catalog/CatalogRedeemVoucherOkEvent'; +import { CatalogSearchEvent } from './messages/incoming/catalog/CatalogSearchEvent'; +import { CatalogSoldOutEvent } from './messages/incoming/catalog/CatalogSoldOutEvent'; +import { CatalogUpdatedEvent } from './messages/incoming/catalog/CatalogUpdatedEvent'; +import { ClientPingEvent } from './messages/incoming/client/ClientPingEvent'; +import { DesktopViewEvent } from './messages/incoming/desktop/DesktopViewEvent'; +import { AcceptFriendResultEvent } from './messages/incoming/friendlist/AcceptFriendResultEvent'; +import { FindFriendsProcessResultEvent } from './messages/incoming/friendlist/FindFriendsProcessResultEvent'; +import { FollowFriendFailedEvent } from './messages/incoming/friendlist/FollowFriendFailedEvent'; +import { FriendListFragmentEvent } from './messages/incoming/friendlist/FriendListFragmentEvent'; +import { FriendListUpdateEvent } from './messages/incoming/friendlist/FriendListUpdateEvent'; +import { FriendNotificationEvent } from './messages/incoming/friendlist/FriendNotificationEvent'; +import { FriendRequestsEvent } from './messages/incoming/friendlist/FriendRequestsEvent'; +import { HabboSearchResultEvent } from './messages/incoming/friendlist/HabboSearchResultEvent'; +import { InstantMessageErrorEvent } from './messages/incoming/friendlist/InstantMessageErrorEvent'; +import { MessageErrorEvent } from './messages/incoming/friendlist/MessageErrorEvent'; +import { MessengerInitEvent } from './messages/incoming/friendlist/MessengerInitEvent'; +import { MiniMailNewMessageEvent } from './messages/incoming/friendlist/MiniMailNewMessageEvent'; +import { NewConsoleMessageEvent } from './messages/incoming/friendlist/NewConsoleMessageEvent'; +import { NewFriendRequestEvent } from './messages/incoming/friendlist/NewFriendRequestEvent'; +import { RoomInviteErrorEvent } from './messages/incoming/friendlist/RoomInviteErrorEvent'; +import { RoomInviteEvent } from './messages/incoming/friendlist/RoomInviteEvent'; +import { LoadGameUrlEvent } from './messages/incoming/game/LoadGameUrlEvent'; +import { GenericErrorEvent } from './messages/incoming/generic/GenericErrorEvent'; +import { GroupBadgePartsEvent } from './messages/incoming/group/GroupBadgePartsEvent'; +import { GroupBuyDataEvent } from './messages/incoming/group/GroupBuyDataEvent'; +import { GroupConfirmMemberRemoveEvent } from './messages/incoming/group/GroupConfirmMemberRemoveEvent'; +import { GroupInformationEvent } from './messages/incoming/group/GroupInformationEvent'; +import { GroupMembersEvent } from './messages/incoming/group/GroupMembersEvent'; +import { GroupSettingsEvent } from './messages/incoming/group/GroupSettingsEvent'; +import { CallForHelpResultMessageEvent } from './messages/incoming/help/CallForHelpResultMessageEvent'; +import { IncomingHeader } from './messages/incoming/IncomingHeader'; +import { AchievementEvent } from './messages/incoming/inventory/achievements/AchievementEvent'; +import { AchievementsEvent } from './messages/incoming/inventory/achievements/AchievementsEvent'; +import { AchievementsScoreEvent } from './messages/incoming/inventory/achievements/AchievementsScoreEvent'; +import { AvatarEffectActivatedEvent } from './messages/incoming/inventory/avatareffect/AvatarEffectActivatedEvent'; +import { AvatarEffectAddedEvent } from './messages/incoming/inventory/avatareffect/AvatarEffectAddedEvent'; +import { AvatarEffectExpiredEvent } from './messages/incoming/inventory/avatareffect/AvatarEffectExpiredEvent'; +import { AvatarEffectsEvent } from './messages/incoming/inventory/avatareffect/AvatarEffectsEvent'; +import { BadgesEvent } from './messages/incoming/inventory/badges/BadgesEvent'; +import { BotAddedToInventoryEvent } from './messages/incoming/inventory/bots/BotAddedToInventoryEvent'; +import { BotInventoryMessageEvent } from './messages/incoming/inventory/bots/BotInventoryMessageEvent'; +import { BotRemovedFromInventoryEvent } from './messages/incoming/inventory/bots/BotRemovedFromInventoryEvent'; +import { FigureSetIdsMessageEvent } from './messages/incoming/inventory/clothes/FigureSetIdsMessageEvent'; +import { FurnitureListAddOrUpdateEvent } from './messages/incoming/inventory/furni/FurnitureListAddOrUpdateEvent'; +import { FurnitureListEvent } from './messages/incoming/inventory/furni/FurnitureListEvent'; +import { FurnitureListInvalidateEvent } from './messages/incoming/inventory/furni/FurnitureListInvalidateEvent'; +import { FurnitureListRemovedEvent } from './messages/incoming/inventory/furni/FurnitureListRemovedEvent'; +import { FurniturePostItPlacedEvent } from './messages/incoming/inventory/furni/FurniturePostItPlacedEvent'; +import { FurnitureGiftOpenedEvent } from './messages/incoming/inventory/furni/gifts/FurnitureGiftOpenedEvent'; +import { PetAddedToInventoryEvent } from './messages/incoming/inventory/pets/PetAddedToInventoryEvent'; +import { PetInventoryEvent } from './messages/incoming/inventory/pets/PetInventoryEvent'; +import { PetRemovedFromInventory } from './messages/incoming/inventory/pets/PetRemovedFromInventoryEvent'; +import { TradingAcceptEvent } from './messages/incoming/inventory/trading/TradingAcceptEvent'; +import { TradingCloseEvent } from './messages/incoming/inventory/trading/TradingCloseEvent'; +import { TradingCompletedEvent } from './messages/incoming/inventory/trading/TradingCompletedEvent'; +import { TradingConfirmationEvent } from './messages/incoming/inventory/trading/TradingConfirmationEvent'; +import { TradingListItemEvent } from './messages/incoming/inventory/trading/TradingListItemEvent'; +import { TradingNotOpenEvent } from './messages/incoming/inventory/trading/TradingNotOpenEvent'; +import { TradingOpenEvent } from './messages/incoming/inventory/trading/TradingOpenEvent'; +import { TradingOpenFailedEvent } from './messages/incoming/inventory/trading/TradingOpenFailedEvent'; +import { TradingOtherNotAllowedEvent } from './messages/incoming/inventory/trading/TradingOtherNotAllowedEvent'; +import { TradingYouAreNotAllowedEvent } from './messages/incoming/inventory/trading/TradingYouAreNotAllowedEvent'; +import { ModeratorMessageEvent } from './messages/incoming/moderation/ModeratorMessageEvent'; +import { ModtoolCallForHelpTopicsEvent } from './messages/incoming/modtool/ModtoolCallForHelpTopicsEvent'; +import { ModtoolMainEvent } from './messages/incoming/modtool/ModtoolMainEvent'; +import { ModtoolReceivedRoomsUserEvent } from './messages/incoming/modtool/ModtoolReceivedRoomsUserEvent'; +import { ModtoolRoomChatlogEvent } from './messages/incoming/modtool/ModtoolRoomChatlogEvent'; +import { ModtoolRoomInfoEvent } from './messages/incoming/modtool/ModtoolRoomInfoEvent'; +import { ModtoolUserChatlogEvent } from './messages/incoming/modtool/ModtoolUserChatlogEvent'; +import { ModtoolUserInfoEvent } from './messages/incoming/modtool/ModtoolUserInfoEvent'; +import { NavigatorCategoriesEvent } from './messages/incoming/navigator/NavigatorCategoriesEvent'; +import { NavigatorCollapsedEvent } from './messages/incoming/navigator/NavigatorCollapsedEvent'; +import { NavigatorEventCategoriesEvent } from './messages/incoming/navigator/NavigatorEventCategoriesEvent'; +import { NavigatorHomeRoomEvent } from './messages/incoming/navigator/NavigatorHomeRoomEvent'; +import { NavigatorLiftedEvent } from './messages/incoming/navigator/NavigatorLiftedEvent'; +import { NavigatorMetadataEvent } from './messages/incoming/navigator/NavigatorMetadataEvent'; +import { NavigatorOpenRoomCreatorEvent } from './messages/incoming/navigator/NavigatorOpenRoomCreatorEvent'; +import { NavigatorSearchesEvent } from './messages/incoming/navigator/NavigatorSearchesEvent'; +import { NavigatorSearchEvent } from './messages/incoming/navigator/NavigatorSearchEvent'; +import { NavigatorSettingsEvent } from './messages/incoming/navigator/NavigatorSettingsEvent'; +import { BotErrorEvent } from './messages/incoming/notifications/BotErrorEvent'; +import { HabboBroadcastMessageEvent } from './messages/incoming/notifications/HabboBroadcastMessageEvent'; +import { HotelWillShutdownEvent } from './messages/incoming/notifications/HotelWillShutdownEvent'; +import { MOTDNotificationEvent } from './messages/incoming/notifications/MOTDNotificationEvent'; +import { NotificationDialogMessageEvent } from './messages/incoming/notifications/NotificationDialogMessageEvent'; +import { PetPlacingErrorEvent } from './messages/incoming/notifications/PetPlacingErrorEvent'; +import { RespectReceivedEvent } from './messages/incoming/notifications/RespectReceivedEvent'; +import { UnseenItemsEvent } from './messages/incoming/notifications/UnseenItemsEvent'; +import { RoomDoorbellAcceptedEvent } from './messages/incoming/room/access/doorbell/RoomDoorbellAcceptedEvent'; +import { RoomDoorbellEvent } from './messages/incoming/room/access/doorbell/RoomDoorbellEvent'; +import { RoomDoorbellRejectedEvent } from './messages/incoming/room/access/doorbell/RoomDoorbellRejectedEvent'; +import { RoomRightsClearEvent } from './messages/incoming/room/access/rights/RoomRightsClearEvent'; +import { RoomRightsEvent } from './messages/incoming/room/access/rights/RoomRightsEvent'; +import { RoomRightsOwnerEvent } from './messages/incoming/room/access/rights/RoomRightsOwnerEvent'; +import { RoomEnterErrorEvent } from './messages/incoming/room/access/RoomEnterErrorEvent'; +import { RoomEnterEvent } from './messages/incoming/room/access/RoomEnterEvent'; +import { RoomForwardEvent } from './messages/incoming/room/access/RoomForwardEvent'; +import { BotCommandConfigurationEvent } from './messages/incoming/room/bots/BotCommandConfigurationEvent'; +import { RoomBannedUsersEvent } from './messages/incoming/room/data/RoomBannedUsersEvent'; +import { RoomChatSettingsEvent } from './messages/incoming/room/data/RoomChatSettingsEvent'; +import { RoomInfoEvent } from './messages/incoming/room/data/RoomInfoEvent'; +import { RoomInfoOwnerEvent } from './messages/incoming/room/data/RoomInfoOwnerEvent'; +import { RoomScoreEvent } from './messages/incoming/room/data/RoomScoreEvent'; +import { RoomSettingsErrorEvent } from './messages/incoming/room/data/RoomSettingsErrorEvent'; +import { RoomSettingsEvent } from './messages/incoming/room/data/RoomSettingsEvent'; +import { RoomSettingsSavedEvent } from './messages/incoming/room/data/RoomSettingsSavedEvent'; +import { RoomSettingsUpdatedEvent } from './messages/incoming/room/data/RoomSettingsUpdatedEvent'; +import { RoomUsersWithRightsEvent } from './messages/incoming/room/data/RoomUsersWithRightsEvent'; +import { ObjectsRollingEvent } from './messages/incoming/room/engine/ObjectsRollingEvent'; +import { RoomCreatedEvent } from './messages/incoming/room/engine/RoomCreatedEvent'; +import { FurnitureFloorAddEvent } from './messages/incoming/room/furniture/floor/FurnitureFloorAddEvent'; +import { FurnitureFloorEvent } from './messages/incoming/room/furniture/floor/FurnitureFloorEvent'; +import { FurnitureFloorRemoveEvent } from './messages/incoming/room/furniture/floor/FurnitureFloorRemoveEvent'; +import { FurnitureFloorUpdateEvent } from './messages/incoming/room/furniture/floor/FurnitureFloorUpdateEvent'; +import { FurnitureAliasesEvent } from './messages/incoming/room/furniture/FurnitureAliasesEvent'; +import { FurnitureDataEvent } from './messages/incoming/room/furniture/FurnitureDataEvent'; +import { FurnitureItemDataEvent } from './messages/incoming/room/furniture/FurnitureItemDataEvent'; +import { FurnitureStackHeightEvent } from './messages/incoming/room/furniture/FurnitureStackHeightEvent'; +import { FurnitureState2Event } from './messages/incoming/room/furniture/FurnitureState2Event'; +import { FurnitureStateEvent } from './messages/incoming/room/furniture/FurnitureStateEvent'; +import { LoveLockFurniFinishedEvent } from './messages/incoming/room/furniture/LoveLockFurniFinishedEvent'; +import { LoveLockFurniFriendConfirmedEvent } from './messages/incoming/room/furniture/LoveLockFurniFriendConfirmedEvent'; +import { LoveLockFurniStartEvent } from './messages/incoming/room/furniture/LoveLockFurniStartEvent'; +import { RoomDimmerPresetsEvent } from './messages/incoming/room/furniture/RoomDimmerPresetsMessageEvent'; +import { FurnitureWallAddEvent } from './messages/incoming/room/furniture/wall/FurnitureWallAddEvent'; +import { FurnitureWallEvent } from './messages/incoming/room/furniture/wall/FurnitureWallEvent'; +import { FurnitureWallRemoveEvent } from './messages/incoming/room/furniture/wall/FurnitureWallRemoveEvent'; +import { FurnitureWallUpdateEvent } from './messages/incoming/room/furniture/wall/FurnitureWallUpdateEvent'; +import { RoomDoorEvent } from './messages/incoming/room/mapping/RoomDoorEvent'; +import { RoomHeightMapEvent } from './messages/incoming/room/mapping/RoomHeightMapEvent'; +import { RoomHeightMapUpdateEvent } from './messages/incoming/room/mapping/RoomHeightMapUpdateEvent'; +import { RoomModelEvent } from './messages/incoming/room/mapping/RoomModelEvent'; +import { RoomModelNameEvent } from './messages/incoming/room/mapping/RoomModelNameEvent'; +import { RoomPaintEvent } from './messages/incoming/room/mapping/RoomPaintEvent'; +import { RoomThicknessEvent } from './messages/incoming/room/mapping/RoomThicknessEvent'; +import { PetFigureUpdateEvent } from './messages/incoming/room/pet/PetFigureUpdateEvent'; +import { PetInfoEvent } from './messages/incoming/room/pet/PetInfoEvent'; +import { YouArePlayingGameEvent } from './messages/incoming/room/session/YouArePlayingGameEvent'; +import { FloodControlEvent } from './messages/incoming/room/unit/chat/FloodControlEvent'; +import { RemainingMuteEvent } from './messages/incoming/room/unit/chat/RemainingMuteEvent'; +import { RoomUnitChatEvent } from './messages/incoming/room/unit/chat/RoomUnitChatEvent'; +import { RoomUnitChatShoutEvent } from './messages/incoming/room/unit/chat/RoomUnitChatShoutEvent'; +import { RoomUnitChatWhisperEvent } from './messages/incoming/room/unit/chat/RoomUnitChatWhisperEvent'; +import { RoomUnitTypingEvent } from './messages/incoming/room/unit/chat/RoomUnitTypingEvent'; +import { RoomUnitDanceEvent } from './messages/incoming/room/unit/RoomUnitDanceEvent'; +import { RoomUnitEffectEvent } from './messages/incoming/room/unit/RoomUnitEffectEvent'; +import { RoomUnitEvent } from './messages/incoming/room/unit/RoomUnitEvent'; +import { RoomUnitExpressionEvent } from './messages/incoming/room/unit/RoomUnitExpressionEvent'; +import { RoomUnitHandItemEvent } from './messages/incoming/room/unit/RoomUnitHandItemEvent'; +import { RoomUnitHandItemReceivedEvent } from './messages/incoming/room/unit/RoomUnitHandItemReceivedEvent'; +import { RoomUnitIdleEvent } from './messages/incoming/room/unit/RoomUnitIdleEvent'; +import { RoomUnitInfoEvent } from './messages/incoming/room/unit/RoomUnitInfoEvent'; +import { RoomUnitNumberEvent } from './messages/incoming/room/unit/RoomUnitNumberEvent'; +import { RoomUnitRemoveEvent } from './messages/incoming/room/unit/RoomUnitRemoveEvent'; +import { RoomUnitStatusEvent } from './messages/incoming/room/unit/RoomUnitStatusEvent'; +import { RoomMutedEvent } from './messages/incoming/roomevents/RoomMutedEvent'; +import { WiredFurniActionEvent } from './messages/incoming/roomevents/WiredFurniActionEvent'; +import { WiredFurniConditionEvent } from './messages/incoming/roomevents/WiredFurniConditionEvent'; +import { WiredFurniTriggerEvent } from './messages/incoming/roomevents/WiredFurniTriggerEvent'; +import { WiredOpenEvent } from './messages/incoming/roomevents/WiredOpenEvent'; +import { WiredRewardResultMessageEvent } from './messages/incoming/roomevents/WiredRewardResultMessageEvent'; +import { WiredSaveSuccessEvent } from './messages/incoming/roomevents/WiredSaveSuccessEvent'; +import { WiredValidationErrorEvent } from './messages/incoming/roomevents/WiredValidationErrorEvent'; +import { AuthenticatedEvent } from './messages/incoming/security/AuthenticatedEvent'; +import { UserPerksEvent } from './messages/incoming/user/access/UserPerksEvent'; +import { UserPermissionsEvent } from './messages/incoming/user/access/UserPermissionsEvent'; +import { UserCurrentBadgesEvent } from './messages/incoming/user/data/UserCurrentBadgesEvent'; +import { UserFigureEvent } from './messages/incoming/user/data/UserFigureEvent'; +import { UserInfoEvent } from './messages/incoming/user/data/UserInfoEvent'; +import { UserNameChangeMessageEvent } from './messages/incoming/user/data/UserNameChangeMessageEvent'; +import { UserProfileEvent } from './messages/incoming/user/data/UserProfileEvent'; +import { UserRelationshipsEvent } from './messages/incoming/user/data/UserRelationshipsEvent'; +import { UserSettingsEvent } from './messages/incoming/user/data/UserSettingsEvent'; +import { IgnoredUsersEvent } from './messages/incoming/user/IgnoredUsersEvent'; +import { IgnoreResultEvent } from './messages/incoming/user/IgnoreResultEvent'; +import { InClientLinkEvent } from './messages/incoming/user/InClientLinkEvent'; +import { UserCreditsEvent } from './messages/incoming/user/inventory/currency/UserCreditsEvent'; +import { UserCurrencyEvent } from './messages/incoming/user/inventory/currency/UserCurrencyEvent'; +import { UserCurrencyUpdateEvent } from './messages/incoming/user/inventory/currency/UserCurrencyUpdateEvent'; +import { UserSubscriptionEvent } from './messages/incoming/user/inventory/subscription/UserSubscriptionEvent'; +import { UserWardrobePageEvent } from './messages/incoming/user/wardrobe/UserWardrobePageEvent'; +import { RequestAchievementsMessageComposer } from './messages/outgoing/achievements/RequestAchievementsMessageComposer'; +import { CatalogGroupsComposer } from './messages/outgoing/catalog/CatalogGroupsComposer'; +import { CatalogModeComposer } from './messages/outgoing/catalog/CatalogModeComposer'; +import { CatalogPageComposer } from './messages/outgoing/catalog/CatalogPageComposer'; +import { CatalogPurchaseComposer } from './messages/outgoing/catalog/CatalogPurchaseComposer'; +import { CatalogPurchaseGiftComposer } from './messages/outgoing/catalog/CatalogPurchaseGiftComposer'; +import { CatalogRequestGiftConfigurationComposer } from './messages/outgoing/catalog/CatalogRequestGiftConfigurationComposer'; +import { CatalogRequestVipGiftsComposer } from './messages/outgoing/catalog/CatalogRequestVipGiftsComposer'; +import { CatalogRequestVipOffersComposer } from './messages/outgoing/catalog/CatalogRequestVipOffersComposer'; +import { CatalogSearchComposer } from './messages/outgoing/catalog/CatalogSearchComposer'; +import { CatalogSelectClubGiftComposer } from './messages/outgoing/catalog/CatalogSelectClubGiftComposer'; +import { RedeemItemClothingComposer } from './messages/outgoing/catalog/RedeemItemClothingComposer'; +import { CatalogRedeemVoucherComposer } from './messages/outgoing/catalog/RedeemVoucherComposer'; +import { ClientPongComposer } from './messages/outgoing/client/ClientPongComposer'; +import { ClientReleaseVersionComposer } from './messages/outgoing/client/ClientReleaseVersionComposer'; +import { DesktopViewComposer } from './messages/outgoing/desktop/DesktopViewComposer'; +import { AcceptFriendComposer } from './messages/outgoing/friendlist/AcceptFriendComposer'; +import { DeclineFriendComposer } from './messages/outgoing/friendlist/DeclineFriendComposer'; +import { FindNewFriendsComposer } from './messages/outgoing/friendlist/FindNewFriendsComposer'; +import { FollowFriendComposer } from './messages/outgoing/friendlist/FollowFriendComposer'; +import { FriendListUpdateComposer } from './messages/outgoing/friendlist/FriendListUpdateComposer'; +import { GetFriendRequestsComposer } from './messages/outgoing/friendlist/GetFriendRequestsComposer'; +import { HabboSearchComposer } from './messages/outgoing/friendlist/HabboSearchComposer'; +import { MessengerInitComposer } from './messages/outgoing/friendlist/MessengerInitComposer'; +import { RemoveFriendComposer } from './messages/outgoing/friendlist/RemoveFriendComposer'; +import { RequestFriendComposer } from './messages/outgoing/friendlist/RequestFriendComposer'; +import { SendMessageComposer } from './messages/outgoing/friendlist/SendMessageComposer'; +import { SendRoomInviteComposer } from './messages/outgoing/friendlist/SendRoomInviteComposer'; +import { SetRelationshipStatusComposer } from './messages/outgoing/friendlist/SetRelationshipStatusComposer'; +import { VisitUserComposer } from './messages/outgoing/friendlist/VisitUserComposer'; +import { GroupAdminGiveComposer } from './messages/outgoing/group/GroupAdminGiveComposer'; +import { GroupAdminTakeComposer } from './messages/outgoing/group/GroupAdminTakeComposer'; +import { GroupBadgePartsComposer } from './messages/outgoing/group/GroupBadgePartsComposer'; +import { GroupBuyComposer } from './messages/outgoing/group/GroupBuyComposer'; +import { GroupBuyDataComposer } from './messages/outgoing/group/GroupBuyDataComposer'; +import { GroupConfirmRemoveMemberComposer } from './messages/outgoing/group/GroupConfirmRemoveMemberComposer'; +import { GroupDeleteComposer } from './messages/outgoing/group/GroupDeleteComposer'; +import { GroupInformationComposer } from './messages/outgoing/group/GroupInformationComposer'; +import { GroupJoinComposer } from './messages/outgoing/group/GroupJoinComposer'; +import { GroupMembersComposer } from './messages/outgoing/group/GroupMembersComposer'; +import { GroupMembershipAcceptComposer } from './messages/outgoing/group/GroupMembershipAcceptComposer'; +import { GroupMembershipDeclineComposer } from './messages/outgoing/group/GroupMembershipDeclineComposer'; +import { GroupRemoveMemberComposer } from './messages/outgoing/group/GroupRemoveMemberComposer'; +import { GroupSaveBadgeComposer } from './messages/outgoing/group/GroupSaveBadgeComposer'; +import { GroupSaveColorsComposer } from './messages/outgoing/group/GroupSaveColorsComposer'; +import { GroupSaveInformationComposer } from './messages/outgoing/group/GroupSaveInformationComposer'; +import { GroupSavePreferencesComposer } from './messages/outgoing/group/GroupSavePreferencesComposer'; +import { GroupSettingsComposer } from './messages/outgoing/group/GroupSettingsComposer'; +import { InfoRetrieveBaseMessageComposer } from './messages/outgoing/handshake/InfoRetrieveBaseMessageComposer'; +import { SecurityTicketComposer } from './messages/outgoing/handshake/SecurityTicketComposer'; +import { RequestBadgesComposer } from './messages/outgoing/inventory/badges/RequestBadgesComposer'; +import { SetActivatedBadgesComposer } from './messages/outgoing/inventory/badges/SetActivatedBadgesComposer'; +import { GetBotInventoryComposer } from './messages/outgoing/inventory/bots/GetBotInventoryComposer'; +import { FurnitureList2Composer } from './messages/outgoing/inventory/furni/FurnitureList2Composer'; +import { FurnitureListComposer } from './messages/outgoing/inventory/furni/FurnitureListComposer'; +import { RequestPetsComposer } from './messages/outgoing/inventory/pets/RequestPetsComposer'; +import { TradingAcceptComposer } from './messages/outgoing/inventory/trading/TradingAcceptComposer'; +import { TradingCancelComposer } from './messages/outgoing/inventory/trading/TradingCancelComposer'; +import { TradingCloseComposer } from './messages/outgoing/inventory/trading/TradingCloseComposer'; +import { TradingConfirmationComposer } from './messages/outgoing/inventory/trading/TradingConfirmationComposer'; +import { TradingListAddItemComposer } from './messages/outgoing/inventory/trading/TradingListAddItemComposer'; +import { TradingListAddItemsComposer } from './messages/outgoing/inventory/trading/TradingListAddItemsComposer'; +import { TradingListItemRemoveComposer } from './messages/outgoing/inventory/trading/TradingListRemoveItemComposer'; +import { TradingOpenComposer } from './messages/outgoing/inventory/trading/TradingOpenComposer'; +import { TradingUnacceptComposer } from './messages/outgoing/inventory/trading/TradingUnacceptComposer'; +import { ModtoolChangeRoomSettingsComposer } from './messages/outgoing/modtool/ModtoolChangeRoomSettingsComposer'; +import { ModtoolEventAlertComposer } from './messages/outgoing/modtool/ModtoolEventAlertComposer'; +import { ModtoolRequestRoomChatlogComposer } from './messages/outgoing/modtool/ModtoolRequestRoomChatlogComposer'; +import { ModtoolRequestRoomInfoComposer } from './messages/outgoing/modtool/ModtoolRequestRoomInfoComposer'; +import { ModtoolRequestUserChatlogComposer } from './messages/outgoing/modtool/ModtoolRequestUserChatlogComposer'; +import { ModtoolRequestUserInfoComposer } from './messages/outgoing/modtool/ModtoolRequestUserInfoComposer'; +import { ModtoolRequestUserRoomsComposer } from './messages/outgoing/modtool/ModtoolRequestUserRoomsComposer'; +import { ModtoolRoomAlertComposer } from './messages/outgoing/modtool/ModtoolRoomAlertComposer'; +import { ModtoolSanctionAlertComposer } from './messages/outgoing/modtool/ModtoolSanctionAlertComposer'; +import { ModtoolSanctionBanComposer } from './messages/outgoing/modtool/ModtoolSanctionBanComposer'; +import { ModtoolSanctionKickComposer } from './messages/outgoing/modtool/ModtoolSanctionKickComposer'; +import { ModtoolSanctionMuteComposer } from './messages/outgoing/modtool/ModtoolSanctionMuteComposer'; +import { ModtoolSanctionTradelockComposer } from './messages/outgoing/modtool/ModtoolSanctionTradelockComposer'; +import { ConvertGlobalRoomIdMessageComposer } from './messages/outgoing/navigator/ConvertGlobalRoomIdComposer'; +import { NavigatorCategoriesComposer } from './messages/outgoing/navigator/NavigatorCategoriesComposer'; +import { NavigatorCategoryListModeComposer } from './messages/outgoing/navigator/NavigatorCategoryListModeComposer'; +import { NavigatorInitComposer } from './messages/outgoing/navigator/NavigatorInitComposer'; +import { NavigatorSearchCloseComposer } from './messages/outgoing/navigator/NavigatorSearchCloseComposer'; +import { NavigatorSearchComposer } from './messages/outgoing/navigator/NavigatorSearchComposer'; +import { NavigatorSearchOpenComposer } from './messages/outgoing/navigator/NavigatorSearchOpenComposer'; +import { NavigatorSearchSaveComposer } from './messages/outgoing/navigator/NavigatorSearchSaveComposer'; +import { NavigatorSettingsComposer } from './messages/outgoing/navigator/NavigatorSettingsComposer'; +import { NavigatorSettingsSaveComposer } from './messages/outgoing/navigator/NavigatorSettingsSaveComposer'; +import { OutgoingHeader } from './messages/outgoing/OutgoingHeader'; +import { PetRespectComposer } from './messages/outgoing/pet/PetRespectComposer'; +import { RequestPetInfoComposer } from './messages/outgoing/pet/RequestPetInfoComposer'; +import { RoomDoorbellAccessComposer } from './messages/outgoing/room/access/RoomDoorbellAccessComposer'; +import { RoomEnterComposer } from './messages/outgoing/room/access/RoomEnterComposer'; +import { RoomAmbassadorAlertComposer } from './messages/outgoing/room/action/RoomAmbassadorAlertComposer'; +import { RoomBanUserComposer } from './messages/outgoing/room/action/RoomBanUserComposer'; +import { RoomDeleteComposer } from './messages/outgoing/room/action/RoomDeleteComposer'; +import { RoomGiveRightsComposer } from './messages/outgoing/room/action/RoomGiveRightsComposer'; +import { RoomKickUserComposer } from './messages/outgoing/room/action/RoomKickUserComposer'; +import { RoomLikeRoomComposer } from './messages/outgoing/room/action/RoomLikeRoomComposer'; +import { RoomMuteUserComposer } from './messages/outgoing/room/action/RoomMuteUserComposer'; +import { RoomStaffPickComposer } from './messages/outgoing/room/action/RoomStaffPickComposer'; +import { RoomTakeRightsComposer } from './messages/outgoing/room/action/RoomTakeRightsComposer'; +import { RoomUnbanUserComposer } from './messages/outgoing/room/action/RoomUnbanUserComposer'; +import { RequestBotCommandConfigurationComposer } from './messages/outgoing/room/bots/RequestBotConfigurationComposer'; +import { RoomBannedUsersComposer } from './messages/outgoing/room/data/RoomBannedUsersComposer'; +import { RoomInfoComposer } from './messages/outgoing/room/data/RoomInfoComposer'; +import { RoomSettingsComposer } from './messages/outgoing/room/data/RoomSettingsComposer'; +import { RoomUsersWithRightsComposer } from './messages/outgoing/room/data/RoomUsersWithRightsComposer'; +import { SaveRoomSettingsComposer } from './messages/outgoing/room/data/SaveRoomSettingsComposer'; +import { BotPlaceComposer } from './messages/outgoing/room/engine/BotPlaceComposer'; +import { BotRemoveComposer } from './messages/outgoing/room/engine/BotRemoveComposer'; +import { BotSkillSaveComposer } from './messages/outgoing/room/engine/BotSkillSaveComposer'; +import { GetItemDataComposer } from './messages/outgoing/room/engine/GetItemDataComposer'; +import { ModifyWallItemDataComposer } from './messages/outgoing/room/engine/ModifyWallItemDataComposer'; +import { PetMoveComposer } from './messages/outgoing/room/engine/PetMoveComposer'; +import { PetPlaceComposer } from './messages/outgoing/room/engine/PetPlaceComposer'; +import { PetRemoveComposer } from './messages/outgoing/room/engine/PetRemoveComposer'; +import { RemoveWallItemComposer } from './messages/outgoing/room/engine/RemoveWallItemComposer'; +import { RoomAdsUpdateComposer } from './messages/outgoing/room/furniture/ads/RoomAdsUpdateComposer'; +import { MoodlightSettingsComposer } from './messages/outgoing/room/furniture/dimmer/MoodlightSettingsComposer'; +import { MoodlightSettingsSaveComposer } from './messages/outgoing/room/furniture/dimmer/MoodlightSettingsSaveComposer'; +import { MoodlightTogggleStateComposer } from './messages/outgoing/room/furniture/dimmer/MoodlightTogggleStateComposer'; +import { FurnitureFloorUpdateComposer } from './messages/outgoing/room/furniture/floor/FurnitureFloorUpdateComposer'; +import { FurnitureAliasesComposer } from './messages/outgoing/room/furniture/FurnitureAliasesComposer'; +import { FurniturePickupComposer } from './messages/outgoing/room/furniture/FurniturePickupComposer'; +import { FurniturePlaceComposer } from './messages/outgoing/room/furniture/FurniturePlaceComposer'; +import { FurniturePlacePaintComposer } from './messages/outgoing/room/furniture/FurniturePlacePaintComposer'; +import { FurniturePostItPlaceComposer } from './messages/outgoing/room/furniture/FurniturePostItPlaceComposer'; +import { FurnitureColorWheelComposer } from './messages/outgoing/room/furniture/logic/FurnitureColorWheelComposer'; +import { FurnitureDiceActivateComposer } from './messages/outgoing/room/furniture/logic/FurnitureDiceActivateComposer'; +import { FurnitureDiceDeactivateComposer } from './messages/outgoing/room/furniture/logic/FurnitureDiceDeactivateComposer'; +import { FurnitureExchangeComposer } from './messages/outgoing/room/furniture/logic/FurnitureExchangeComposer'; +import { FurnitureMultiStateComposer } from './messages/outgoing/room/furniture/logic/FurnitureMultiStateComposer'; +import { FurnitureOneWayDoorComposer } from './messages/outgoing/room/furniture/logic/FurnitureOneWayDoorComposer'; +import { FurnitureRandomStateComposer } from './messages/outgoing/room/furniture/logic/FurnitureRandomStateComposer'; +import { FurnitureStackHeightComposer } from './messages/outgoing/room/furniture/logic/FurnitureStackHeightComposer'; +import { FurnitureWallMultiStateComposer } from './messages/outgoing/room/furniture/logic/FurnitureWallMultiStateComposer'; +import { LoveLockStartConfirmComposer } from './messages/outgoing/room/furniture/logic/LoveLockStartConfirmComposer'; +import { FurnitureMannequinSaveLookComposer } from './messages/outgoing/room/furniture/mannequin/FurnitureMannequinSaveLookComposer'; +import { FurnitureMannequinSaveNameComposer } from './messages/outgoing/room/furniture/mannequin/FurnitureMannequinSaveNameComposer'; +import { OpenPresentComposer } from './messages/outgoing/room/furniture/presents/OpenPresentComposer'; +import { ApplyTonerComposer } from './messages/outgoing/room/furniture/toner/ApplyTonerComposer'; +import { FurnitureWallUpdateComposer } from './messages/outgoing/room/furniture/wall/FurnitureWallUpdateComposer'; +import { RoomModelComposer } from './messages/outgoing/room/mapping/RoomModelComposer'; +import { RoomCreateComposer } from './messages/outgoing/room/RoomCreateComposer'; +import { RoomUnitChatComposer } from './messages/outgoing/room/unit/chat/RoomUnitChatComposer'; +import { RoomUnitChatShoutComposer } from './messages/outgoing/room/unit/chat/RoomUnitChatShoutComposer'; +import { RoomUnitChatStyleComposer } from './messages/outgoing/room/unit/chat/RoomUnitChatStyleComposer'; +import { RoomUnitChatWhisperComposer } from './messages/outgoing/room/unit/chat/RoomUnitChatWhisperComposer'; +import { RoomUnitTypingStartComposer } from './messages/outgoing/room/unit/chat/RoomUnitTypingStartComposer'; +import { RoomUnitTypingStopComposer } from './messages/outgoing/room/unit/chat/RoomUnitTypingStopComposer'; +import { RoomUnitActionComposer } from './messages/outgoing/room/unit/RoomUnitActionComposer'; +import { RoomUnitDanceComposer } from './messages/outgoing/room/unit/RoomUnitDanceComposer'; +import { RoomUnitDropHandItemComposer } from './messages/outgoing/room/unit/RoomUnitDropHandItemComposer'; +import { RoomUnitGiveHandItemComposer } from './messages/outgoing/room/unit/RoomUnitGiveHandItemComposer'; +import { RoomUnitLookComposer } from './messages/outgoing/room/unit/RoomUnitLookComposer'; +import { RoomUnitPostureComposer } from './messages/outgoing/room/unit/RoomUnitPostureComposer'; +import { RoomUnitSignComposer } from './messages/outgoing/room/unit/RoomUnitSignComposer'; +import { RoomUnitWalkComposer } from './messages/outgoing/room/unit/RoomUnitWalkComposer'; +import { ApplySnapshotMessageComposer } from './messages/outgoing/roomevents/ApplySnapshotMessageComposer'; +import { OpenMessageComposer } from './messages/outgoing/roomevents/OpenMessageComposer'; +import { RoomMuteComposer } from './messages/outgoing/roomevents/RoomMuteComposer'; +import { UpdateActionMessageComposer } from './messages/outgoing/roomevents/UpdateActionMessageComposer'; +import { UpdateConditionMessageComposer } from './messages/outgoing/roomevents/UpdateConditionMessageComposer'; +import { UpdateTriggerMessageComposer } from './messages/outgoing/roomevents/UpdateTriggerMessageComposer'; +import { GetIgnoredUsersComposer } from './messages/outgoing/user/data/GetIgnoredUsersComposer'; +import { IgnoreUserComposer } from './messages/outgoing/user/data/IgnoreUserComposer'; +import { IgnoreUserIdComposer } from './messages/outgoing/user/data/IgnoreUserIdComposer'; +import { UnignoreUserComposer } from './messages/outgoing/user/data/UnignoreUserComposer'; +import { UserCurrentBadgesComposer } from './messages/outgoing/user/data/UserCurrentBadgesComposer'; +import { UserFigureComposer } from './messages/outgoing/user/data/UserFigureComposer'; +import { UserHomeRoomComposer } from './messages/outgoing/user/data/UserHomeRoomComposer'; +import { UserMottoComposer } from './messages/outgoing/user/data/UserMottoComposer'; +import { UserProfileComposer } from './messages/outgoing/user/data/UserProfileComposer'; +import { UserRelationshipsComposer } from './messages/outgoing/user/data/UserRelationshipsComposer'; +import { UserCurrencyComposer } from './messages/outgoing/user/inventory/currency/UserCurrencyComposer'; +import { UserSubscriptionComposer } from './messages/outgoing/user/inventory/subscription/UserSubscriptionComposer'; +import { UserSettingsCameraFollowComposer } from './messages/outgoing/user/settings/UserSettingsCameraFollowComposer'; +import { UserSettingsOldChatComposer } from './messages/outgoing/user/settings/UserSettingsOldChatComposer'; +import { UserSettingsRoomInvitesComposer } from './messages/outgoing/user/settings/UserSettingsRoomInvitesComposer'; +import { UserSettingsSoundComposer } from './messages/outgoing/user/settings/UserSettingsSoundComposer'; +import { UserRespectComposer } from './messages/outgoing/user/UserRespectComposer'; +import { UserWardrobePageComposer } from './messages/outgoing/user/wardrobe/UserWardrobePageComposer'; +import { UserWardrobeSaveComposer } from './messages/outgoing/user/wardrobe/UserWardrobeSaveComposer'; +import { MiniMailUnreadCountParser } from './messages/parser/friendlist/MiniMailUnreadCountParser'; + +export class NitroMessages implements IMessageConfiguration +{ + private _events: Map; + private _composers: Map; + + constructor() + { + this._events = new Map(); + this._composers = new Map(); + + this.registerEvents(); + this.registerComposers(); + } + + private registerEvents(): void + { + // AVAILABILITY + this._events.set(IncomingHeader.AVAILABILITY_STATUS, AvailabilityStatusMessageEvent); + this._events.set(IncomingHeader.GENERIC_ERROR, GenericErrorEvent); + + // AVATAR + this._events.set(IncomingHeader.USER_CHANGE_NAME, ChangeNameUpdateEvent); + + // CATALOG + this._events.set(IncomingHeader.CATALOG_CLUB, CatalogClubEvent); + this._events.set(IncomingHeader.CATALOG_MODE, CatalogModeEvent); + this._events.set(IncomingHeader.CATALOG_PAGE, CatalogPageEvent); + this._events.set(IncomingHeader.CATALOG_PAGES, CatalogPagesEvent); + this._events.set(IncomingHeader.CATALOG_PURCHASE, CatalogPurchaseEvent); + this._events.set(IncomingHeader.CATALOG_PURCHASE_FAILED, CatalogPurchaseFailedEvent); + this._events.set(IncomingHeader.CATALOG_PURCHASE_UNAVAILABLE, CatalogPurchaseUnavailableEvent); + this._events.set(IncomingHeader.CATALOG_SEARCH, CatalogSearchEvent); + this._events.set(IncomingHeader.CATALOG_SOLD_OUT, CatalogSoldOutEvent); + this._events.set(IncomingHeader.CATALOG_UPDATED, CatalogUpdatedEvent); + this._events.set(IncomingHeader.CATALOG_CLUB_GIFTS, CatalogClubGiftsEvent); + this._events.set(IncomingHeader.GROUP_LIST, CatalogGroupsEvent); + this._events.set(IncomingHeader.GIFT_CONFIG, CatalogGiftConfigurationEvent); + this._events.set(IncomingHeader.REDEEM_VOUCHER_ERROR, CatalogRedeemVoucherErrorEvent); + this._events.set(IncomingHeader.REDEEM_VOUCHER_OK, CatalogRedeemVoucherOkEvent); + + // CLIENT + this._events.set(IncomingHeader.CLIENT_PING, ClientPingEvent); + + // DESKTOP + this._events.set(IncomingHeader.DESKTOP_VIEW, DesktopViewEvent); + + // FRIENDLIST + this._events.set(IncomingHeader.MESSENGER_ACCEPT_FRIENDS, AcceptFriendResultEvent); + this._events.set(IncomingHeader.MESSENGER_FIND_FRIENDS, FindFriendsProcessResultEvent); + this._events.set(IncomingHeader.MESSENGER_FOLLOW_FAILED, FollowFriendFailedEvent); + this._events.set(IncomingHeader.MESSENGER_FRIENDS, FriendListFragmentEvent); + this._events.set(IncomingHeader.MESSENGER_UPDATE, FriendListUpdateEvent); + this._events.set(IncomingHeader.MESSENGER_FRIEND_NOTIFICATION, FriendNotificationEvent); + this._events.set(IncomingHeader.MESSENGER_REQUESTS, FriendRequestsEvent); + this._events.set(IncomingHeader.MESSENGER_SEARCH, HabboSearchResultEvent); + this._events.set(IncomingHeader.MESSENGER_INSTANCE_MESSAGE_ERROR, InstantMessageErrorEvent); + this._events.set(IncomingHeader.MESSENGER_MESSAGE_ERROR, MessageErrorEvent); + this._events.set(IncomingHeader.MESSENGER_INIT, MessengerInitEvent); + this._events.set(IncomingHeader.MESSENGER_MINIMAIL_NEW, MiniMailNewMessageEvent); + this._events.set(IncomingHeader.MESSENGER_MINIMAIL_COUNT, MiniMailUnreadCountParser); + this._events.set(IncomingHeader.MESSENGER_CHAT, NewConsoleMessageEvent); + this._events.set(IncomingHeader.MESSENGER_REQUEST, NewFriendRequestEvent); + this._events.set(IncomingHeader.MESSENGER_INVITE_ERROR, RoomInviteErrorEvent); + this._events.set(IncomingHeader.MESSENGER_INVITE, RoomInviteEvent); + + // GROUP + this._events.set(IncomingHeader.GROUP_INFO, GroupInformationEvent); + this._events.set(IncomingHeader.GROUP_MEMBER_REMOVE_CONFIRM, GroupConfirmMemberRemoveEvent); + this._events.set(IncomingHeader.GROUP_MEMBERS, GroupMembersEvent); + this._events.set(IncomingHeader.GROUP_CREATE_OPTIONS, GroupBuyDataEvent); + this._events.set(IncomingHeader.GROUP_BADGE_PARTS, GroupBadgePartsEvent); + this._events.set(IncomingHeader.GROUP_SETTINGS, GroupSettingsEvent); + + // HELP + this._events.set(IncomingHeader.CFH_RESULT_MESSAGE, CallForHelpResultMessageEvent); + + // INVENTORY + + // ACHIEVEMENTS + this._events.set(IncomingHeader.ACHIEVEMENT_PROGRESSED, AchievementEvent); + this._events.set(IncomingHeader.ACHIEVEMENT_LIST, AchievementsEvent); + this._events.set(IncomingHeader.USER_ACHIEVEMENT_SCORE,AchievementsScoreEvent); + + // EFFECTS + this._events.set(IncomingHeader.USER_EFFECT_ACTIVATE, AvatarEffectActivatedEvent); + this._events.set(IncomingHeader.USER_EFFECT_LIST_ADD, AvatarEffectAddedEvent); + this._events.set(IncomingHeader.USER_EFFECT_LIST_REMOVE, AvatarEffectExpiredEvent); + this._events.set(IncomingHeader.USER_EFFECT_LIST, AvatarEffectsEvent); + + // CLOTHES + this._events.set(IncomingHeader.USER_CLOTHING, FigureSetIdsMessageEvent); + + // FURNITURE + this._events.set(IncomingHeader.USER_FURNITURE_ADD, FurnitureListAddOrUpdateEvent); + this._events.set(IncomingHeader.USER_FURNITURE, FurnitureListEvent); + this._events.set(IncomingHeader.USER_FURNITURE_REFRESH, FurnitureListInvalidateEvent); + this._events.set(IncomingHeader.USER_FURNITURE_REMOVE, FurnitureListRemovedEvent); + this._events.set(IncomingHeader.USER_FURNITURE_POSTIT_PLACED, FurniturePostItPlacedEvent); + + // TRADING + this._events.set(IncomingHeader.TRADE_ACCEPTED, TradingAcceptEvent); + this._events.set(IncomingHeader.TRADE_CLOSED, TradingCloseEvent); + this._events.set(IncomingHeader.TRADE_COMPLETED, TradingCompletedEvent); + this._events.set(IncomingHeader.TRADE_CONFIRMATION, TradingConfirmationEvent); + this._events.set(IncomingHeader.TRADE_LIST_ITEM, TradingListItemEvent); + this._events.set(IncomingHeader.TRADE_NOT_OPEN, TradingNotOpenEvent); + this._events.set(IncomingHeader.TRADE_OPEN_FAILED, TradingOpenFailedEvent); + this._events.set(IncomingHeader.TRADE_OPEN, TradingOpenEvent); + this._events.set(IncomingHeader.TRADE_OTHER_NOT_ALLOWED, TradingOtherNotAllowedEvent); + this._events.set(IncomingHeader.TRADE_YOU_NOT_ALLOWED, TradingYouAreNotAllowedEvent); + + // MODERATION + this._events.set(IncomingHeader.GENERIC_ALERT_LINK, ModeratorMessageEvent); + + // MODTOOL + this._events.set(IncomingHeader.MODTOOL_ROOM_INFO, ModtoolRoomInfoEvent); + this._events.set(IncomingHeader.MODTOOL_USER_CHATLOG, ModtoolUserChatlogEvent); + this._events.set(IncomingHeader.MODTOOL_ROOM_CHATLOG, ModtoolRoomChatlogEvent); + + // NAVIGATOR + this._events.set(IncomingHeader.NAVIGATOR_CATEGORIES, NavigatorCategoriesEvent); + this._events.set(IncomingHeader.NAVIGATOR_COLLAPSED, NavigatorCollapsedEvent); + this._events.set(IncomingHeader.NAVIGATOR_EVENT_CATEGORIES, NavigatorEventCategoriesEvent); + this._events.set(IncomingHeader.USER_HOME_ROOM, NavigatorHomeRoomEvent); + this._events.set(IncomingHeader.NAVIGATOR_LIFTED, NavigatorLiftedEvent); + this._events.set(IncomingHeader.NAVIGATOR_METADATA, NavigatorMetadataEvent); + this._events.set(IncomingHeader.NAVIGATOR_OPEN_ROOM_CREATOR, NavigatorOpenRoomCreatorEvent); + this._events.set(IncomingHeader.NAVIGATOR_SEARCHES, NavigatorSearchesEvent); + this._events.set(IncomingHeader.NAVIGATOR_SEARCH, NavigatorSearchEvent); + this._events.set(IncomingHeader.NAVIGATOR_SETTINGS, NavigatorSettingsEvent); + + // NOTIFICATIONS + this._events.set(IncomingHeader.GENERIC_ALERT, HabboBroadcastMessageEvent); + this._events.set(IncomingHeader.MOTD_MESSAGES, MOTDNotificationEvent); + this._events.set(IncomingHeader.NOTIFICATION_LIST, NotificationDialogMessageEvent); + this._events.set(IncomingHeader.USER_RESPECT, RespectReceivedEvent); + this._events.set(IncomingHeader.UNSEEN_ITEMS, UnseenItemsEvent); + this._events.set(IncomingHeader.HOTEL_WILL_SHUTDOWN, HotelWillShutdownEvent); + + // ROOM + + // ACCESS + this._events.set(IncomingHeader.ROOM_ENTER_ERROR, RoomEnterErrorEvent); + this._events.set(IncomingHeader.ROOM_ENTER, RoomEnterEvent); + this._events.set(IncomingHeader.ROOM_FORWARD, RoomForwardEvent); + + // DOORBELL + this._events.set(IncomingHeader.ROOM_DOORBELL, RoomDoorbellEvent); + this._events.set(IncomingHeader.ROOM_DOORBELL_ACCEPTED, RoomDoorbellAcceptedEvent); + this._events.set(IncomingHeader.ROOM_DOORBELL_REJECTED, RoomDoorbellRejectedEvent); + + // RIGHTS + this._events.set(IncomingHeader.ROOM_RIGHTS_CLEAR, RoomRightsClearEvent); + this._events.set(IncomingHeader.ROOM_RIGHTS_OWNER, RoomRightsOwnerEvent); + this._events.set(IncomingHeader.ROOM_RIGHTS, RoomRightsEvent); + + // DATA + this._events.set(IncomingHeader.ROOM_SETTINGS_CHAT, RoomChatSettingsEvent); + this._events.set(IncomingHeader.ROOM_INFO, RoomInfoEvent); + this._events.set(IncomingHeader.ROOM_INFO_OWNER, RoomInfoOwnerEvent); + this._events.set(IncomingHeader.ROOM_SCORE, RoomScoreEvent); + this._events.set(IncomingHeader.ROOM_SETTINGS_SAVE_ERROR, RoomSettingsErrorEvent); + this._events.set(IncomingHeader.ROOM_SETTINGS, RoomSettingsEvent); + this._events.set(IncomingHeader.ROOM_SETTINGS_SAVE, RoomSettingsSavedEvent); + this._events.set(IncomingHeader.ROOM_SETTINGS_UPDATED, RoomSettingsUpdatedEvent); + this._events.set(IncomingHeader.ROOM_RIGHTS_LIST, RoomUsersWithRightsEvent); + this._events.set(IncomingHeader.ROOM_BAN_LIST, RoomBannedUsersEvent); + + // ENGINE + this._events.set(IncomingHeader.ROOM_ROLLING, ObjectsRollingEvent); + this._events.set(IncomingHeader.ROOM_CREATED, RoomCreatedEvent); + + // BOTS + this._events.set(IncomingHeader.BOT_COMMAND_CONFIGURATION, BotCommandConfigurationEvent); + this._events.set(IncomingHeader.BOT_ERROR, BotErrorEvent); + + // FURNITURE + this._events.set(IncomingHeader.FURNITURE_ALIASES, FurnitureAliasesEvent); + this._events.set(IncomingHeader.FURNITURE_DATA, FurnitureDataEvent); + this._events.set(IncomingHeader.FURNITURE_ITEMDATA, FurnitureItemDataEvent); + this._events.set(IncomingHeader.ITEM_STACK_HELPER, FurnitureStackHeightEvent); + this._events.set(IncomingHeader.FURNITURE_STATE, FurnitureStateEvent); + this._events.set(IncomingHeader.ITEM_DIMMER_SETTINGS, RoomDimmerPresetsEvent); + this._events.set(IncomingHeader.FURNITURE_STATE_2, FurnitureState2Event); + this._events.set(IncomingHeader.LOVELOCK_FURNI_FINISHED, LoveLockFurniFinishedEvent); + this._events.set(IncomingHeader.LOVELOCK_FURNI_FRIEND_COMFIRMED, LoveLockFurniFriendConfirmedEvent); + this._events.set(IncomingHeader.LOVELOCK_FURNI_START, LoveLockFurniStartEvent); + + // FLOOR + this._events.set(IncomingHeader.FURNITURE_FLOOR_ADD, FurnitureFloorAddEvent); + this._events.set(IncomingHeader.FURNITURE_FLOOR, FurnitureFloorEvent); + this._events.set(IncomingHeader.FURNITURE_FLOOR_REMOVE, FurnitureFloorRemoveEvent); + this._events.set(IncomingHeader.FURNITURE_FLOOR_UPDATE, FurnitureFloorUpdateEvent); + + // WALL + this._events.set(IncomingHeader.ITEM_WALL_ADD, FurnitureWallAddEvent); + this._events.set(IncomingHeader.ITEM_WALL, FurnitureWallEvent); + this._events.set(IncomingHeader.ITEM_WALL_REMOVE, FurnitureWallRemoveEvent); + this._events.set(IncomingHeader.ITEM_WALL_UPDATE, FurnitureWallUpdateEvent); + + // MAPPING + this._events.set(IncomingHeader.ROOM_MODEL_DOOR, RoomDoorEvent); + this._events.set(IncomingHeader.ROOM_HEIGHT_MAP, RoomHeightMapEvent); + this._events.set(IncomingHeader.ROOM_HEIGHT_MAP_UPDATE, RoomHeightMapUpdateEvent); + this._events.set(IncomingHeader.ROOM_MODEL, RoomModelEvent); + this._events.set(IncomingHeader.ROOM_MODEL_NAME, RoomModelNameEvent); + this._events.set(IncomingHeader.ROOM_PAINT, RoomPaintEvent); + this._events.set(IncomingHeader.ROOM_THICKNESS, RoomThicknessEvent); + + // PET + this._events.set(IncomingHeader.PET_FIGURE_UPDATE, PetFigureUpdateEvent); + this._events.set(IncomingHeader.PET_INFO, PetInfoEvent); + + // SESSION + this._events.set(IncomingHeader.PLAYING_GAME, YouArePlayingGameEvent); + + // UNIT + this._events.set(IncomingHeader.UNIT_DANCE, RoomUnitDanceEvent); + this._events.set(IncomingHeader.UNIT_EFFECT, RoomUnitEffectEvent); + this._events.set(IncomingHeader.UNIT, RoomUnitEvent); + this._events.set(IncomingHeader.UNIT_EXPRESSION, RoomUnitExpressionEvent); + this._events.set(IncomingHeader.UNIT_HAND_ITEM, RoomUnitHandItemEvent); + this._events.set(IncomingHeader.UNIT_IDLE, RoomUnitIdleEvent); + this._events.set(IncomingHeader.UNIT_INFO, RoomUnitInfoEvent); + this._events.set(IncomingHeader.UNIT_NUMBER, RoomUnitNumberEvent); + this._events.set(IncomingHeader.UNIT_REMOVE, RoomUnitRemoveEvent); + this._events.set(IncomingHeader.UNIT_STATUS, RoomUnitStatusEvent); + this._events.set(IncomingHeader.HAND_ITEM_RECEIVED, RoomUnitHandItemReceivedEvent); + + // CHAT + this._events.set(IncomingHeader.FLOOD_CONTROL, FloodControlEvent); + this._events.set(IncomingHeader.REMAINING_MUTE, RemainingMuteEvent); + this._events.set(IncomingHeader.UNIT_CHAT, RoomUnitChatEvent); + this._events.set(IncomingHeader.UNIT_CHAT_SHOUT, RoomUnitChatShoutEvent); + this._events.set(IncomingHeader.UNIT_CHAT_WHISPER, RoomUnitChatWhisperEvent); + this._events.set(IncomingHeader.UNIT_TYPING, RoomUnitTypingEvent); + + // ROOM EVENTS + this._events.set(IncomingHeader.WIRED_ACTION, WiredFurniActionEvent); + this._events.set(IncomingHeader.WIRED_CONDITION, WiredFurniConditionEvent); + this._events.set(IncomingHeader.WIRED_TRIGGER, WiredFurniTriggerEvent); + this._events.set(IncomingHeader.WIRED_OPEN, WiredOpenEvent); + this._events.set(IncomingHeader.WIRED_REWARD, WiredRewardResultMessageEvent); + this._events.set(IncomingHeader.WIRED_SAVE, WiredSaveSuccessEvent); + this._events.set(IncomingHeader.WIRED_ERROR, WiredValidationErrorEvent); + this._events.set(IncomingHeader.ROOM_MUTED, RoomMutedEvent); + + // SECURITY + this._events.set(IncomingHeader.AUTHENTICATED, AuthenticatedEvent); + + // USER + this._events.set(IncomingHeader.IN_CLIENT_LINK, InClientLinkEvent); + this._events.set(IncomingHeader.USER_IGNORED, IgnoredUsersEvent); + this._events.set(IncomingHeader.USER_IGNORED_RESULT, IgnoreResultEvent); + + // BADGES + this._events.set(IncomingHeader.USER_BADGES, BadgesEvent); + + // ACCESS + this._events.set(IncomingHeader.USER_PERKS, UserPerksEvent); + this._events.set(IncomingHeader.USER_PERMISSIONS, UserPermissionsEvent); + + // DATA + this._events.set(IncomingHeader.USER_BADGES_CURRENT, UserCurrentBadgesEvent); + this._events.set(IncomingHeader.USER_FIGURE, UserFigureEvent); + this._events.set(IncomingHeader.USER_INFO, UserInfoEvent); + this._events.set(IncomingHeader.UNIT_CHANGE_NAME, UserNameChangeMessageEvent); + this._events.set(IncomingHeader.USER_SETTINGS, UserSettingsEvent); + this._events.set(IncomingHeader.USER_PROFILE, UserProfileEvent); + this._events.set(IncomingHeader.MESSENGER_RELATIONSHIPS, UserRelationshipsEvent); + + // GIFTS + this._events.set(IncomingHeader.GIFT_OPENED, FurnitureGiftOpenedEvent); + + // INVENTORY + this._events.set(IncomingHeader.GIFT_RECEIVER_NOT_FOUND, CatalogGiftUsernameUnavailableEvent); + + // BOTS + this._events.set(IncomingHeader.USER_BOTS, BotInventoryMessageEvent); + this._events.set(IncomingHeader.REMOVE_BOT_FROM_INVENTORY, BotRemovedFromInventoryEvent); + this._events.set(IncomingHeader.ADD_BOT_TO_INVENTORY, BotAddedToInventoryEvent); + + // CURRENCY + this._events.set(IncomingHeader.USER_CREDITS, UserCreditsEvent); + this._events.set(IncomingHeader.USER_CURRENCY, UserCurrencyEvent); + this._events.set(IncomingHeader.USER_CURRENCY_UPDATE, UserCurrencyUpdateEvent); + + // SUBSCRIPTION + this._events.set(IncomingHeader.USER_SUBSCRIPTION, UserSubscriptionEvent); + + // GAMES + this._events.set(IncomingHeader.LOAD_GAME_URL, LoadGameUrlEvent); + + // WARDROBE + this._events.set(IncomingHeader.USER_WARDROBE_PAGE, UserWardrobePageEvent); + + // PETS + this._events.set(IncomingHeader.USER_PETS, PetInventoryEvent); + this._events.set(IncomingHeader.USER_PET_REMOVE, PetRemovedFromInventory); + this._events.set(IncomingHeader.USER_PET_ADD, PetAddedToInventoryEvent); + this._events.set(IncomingHeader.PET_PLACING_ERROR, PetPlacingErrorEvent); + + // MOD TOOL + this._events.set(IncomingHeader.MODERATION_USER_INFO, ModtoolUserInfoEvent); + this._events.set(IncomingHeader.MODERATION_TOPICS, ModtoolCallForHelpTopicsEvent); + this._events.set(IncomingHeader.MODERATION_TOOL, ModtoolMainEvent); + this._events.set(IncomingHeader.MODTOOL_VISITED_ROOMS_USER, ModtoolReceivedRoomsUserEvent); + } + + private registerComposers(): void + { + // CATALOG + this._composers.set(OutgoingHeader.CATALOG_MODE, CatalogModeComposer); + this._composers.set(OutgoingHeader.CATALOG_PAGE, CatalogPageComposer); + this._composers.set(OutgoingHeader.CATALOG_PURCHASE, CatalogPurchaseComposer); + this._composers.set(OutgoingHeader.CATALOG_PURCHASE_GIFT, CatalogPurchaseGiftComposer); + this._composers.set(OutgoingHeader.CATALOG_SEARCH, CatalogSearchComposer); + this._composers.set(OutgoingHeader.CATALOG_CLUB, CatalogRequestVipOffersComposer); + this._composers.set(OutgoingHeader.CATALOG_CLUB_GIFTS, CatalogRequestVipGiftsComposer); + this._composers.set(OutgoingHeader.CATALOG_REDEEM_VOUCHER, CatalogRedeemVoucherComposer); + this._composers.set(OutgoingHeader.LOVELOCK_START_CONFIRM, LoveLockStartConfirmComposer); + this._composers.set(OutgoingHeader.GROUP_MEMBERSHIPS, CatalogGroupsComposer); + this._composers.set(OutgoingHeader.GIFT_CONFIG, CatalogRequestGiftConfigurationComposer); + this._composers.set(OutgoingHeader.CATALOG_SELECT_VIP_GIFT, CatalogSelectClubGiftComposer); + + // CLIENT + this._composers.set(OutgoingHeader.CLIENT_PONG, ClientPongComposer); + this._composers.set(OutgoingHeader.RELEASE_VERSION, ClientReleaseVersionComposer); + + // DESKTOP + this._composers.set(OutgoingHeader.DESKTOP_VIEW, DesktopViewComposer); + + // FRIENDLIST + this._composers.set(OutgoingHeader.MESSENGER_ACCEPT, AcceptFriendComposer); + this._composers.set(OutgoingHeader.MESSENGER_DECLINE, DeclineFriendComposer); + this._composers.set(OutgoingHeader.FIND_FRIENDS, FindNewFriendsComposer); + this._composers.set(OutgoingHeader.MESSENGER_FOLLOW, FollowFriendComposer); + this._composers.set(OutgoingHeader.MESSENGER_UPDATES, FriendListUpdateComposer); + this._composers.set(OutgoingHeader.MESSENGER_REQUESTS, GetFriendRequestsComposer); + this._composers.set(OutgoingHeader.MESSENGER_SEARCH, HabboSearchComposer); + this._composers.set(OutgoingHeader.MESSENGER_INIT, MessengerInitComposer); + this._composers.set(OutgoingHeader.MESSENGER_REMOVE, RemoveFriendComposer); + this._composers.set(OutgoingHeader.MESSENGER_REQUEST, RequestFriendComposer); + this._composers.set(OutgoingHeader.MESSENGER_CHAT, SendMessageComposer); + this._composers.set(OutgoingHeader.MESSENGER_ROOM_INVITE, SendRoomInviteComposer); + this._composers.set(OutgoingHeader.MESSENGER_RELATIONSHIPS_UPDATE, SetRelationshipStatusComposer); + this._composers.set(OutgoingHeader.USER_VISIT, VisitUserComposer); + + // GROUP + this._composers.set(OutgoingHeader.GROUP_INFO, GroupInformationComposer); + this._composers.set(OutgoingHeader.GROUP_REQUEST, GroupJoinComposer); + this._composers.set(OutgoingHeader.GROUP_MEMBER_REMOVE_CONFIRM, GroupConfirmRemoveMemberComposer); + this._composers.set(OutgoingHeader.GROUP_MEMBER_REMOVE, GroupRemoveMemberComposer); + this._composers.set(OutgoingHeader.GROUP_MEMBERS, GroupMembersComposer); + this._composers.set(OutgoingHeader.GROUP_ADMIN_ADD, GroupAdminGiveComposer); + this._composers.set(OutgoingHeader.GROUP_ADMIN_REMOVE, GroupAdminTakeComposer); + this._composers.set(OutgoingHeader.GROUP_REQUEST_ACCEPT, GroupMembershipAcceptComposer); + this._composers.set(OutgoingHeader.GROUP_REQUEST_DECLINE, GroupMembershipDeclineComposer); + this._composers.set(OutgoingHeader.GROUP_DELETE, GroupDeleteComposer); + this._composers.set(OutgoingHeader.GROUP_CREATE_OPTIONS, GroupBuyDataComposer); + this._composers.set(OutgoingHeader.GROUP_PARTS, GroupBadgePartsComposer); + this._composers.set(OutgoingHeader.GROUP_BUY, GroupBuyComposer); + this._composers.set(OutgoingHeader.GROUP_SETTINGS, GroupSettingsComposer); + this._composers.set(OutgoingHeader.GROUP_SAVE_BADGE, GroupSaveBadgeComposer); + this._composers.set(OutgoingHeader.GROUP_SAVE_COLORS, GroupSaveColorsComposer); + this._composers.set(OutgoingHeader.GROUP_SAVE_INFORMATION, GroupSaveInformationComposer); + this._composers.set(OutgoingHeader.GROUP_SAVE_PREFERENCES, GroupSavePreferencesComposer); + + // SECURITY + this._composers.set(OutgoingHeader.SECURITY_TICKET, SecurityTicketComposer); + this._composers.set(OutgoingHeader.USER_INFO, InfoRetrieveBaseMessageComposer); + + // NAVIGATOR + this._composers.set(OutgoingHeader.NAVIGATOR_CATEGORIES, NavigatorCategoriesComposer); + this._composers.set(OutgoingHeader.NAVIGATOR_INIT, NavigatorInitComposer); + this._composers.set(OutgoingHeader.NAVIGATOR_SEARCH_CLOSE, NavigatorSearchCloseComposer); + this._composers.set(OutgoingHeader.NAVIGATOR_SEARCH, NavigatorSearchComposer); + this._composers.set(OutgoingHeader.NAVIGATOR_SEARCH_OPEN, NavigatorSearchOpenComposer); + this._composers.set(OutgoingHeader.NAVIGATOR_SEARCH_SAVE, NavigatorSearchSaveComposer); + this._composers.set(OutgoingHeader.NAVIGATOR_SETTINGS, NavigatorSettingsComposer); + this._composers.set(OutgoingHeader.NAVIGATOR_SETTINGS_SAVE, NavigatorSettingsSaveComposer); + this._composers.set(OutgoingHeader.NAVIGATOR_CATEGORY_LIST_MODE, NavigatorCategoryListModeComposer); + this._composers.set(OutgoingHeader.CONVERT_GLOBAL_ROOM_ID, ConvertGlobalRoomIdMessageComposer); + + // INVENTORY + + // FURNI + this._composers.set(OutgoingHeader.USER_FURNITURE, FurnitureListComposer); + this._composers.set(OutgoingHeader.USER_FURNITURE2, FurnitureList2Composer); + this._composers.set(OutgoingHeader.ITEM_SAVE_BACKGROUND, RoomAdsUpdateComposer); + + // TRADING + this._composers.set(OutgoingHeader.TRADE_ACCEPT, TradingAcceptComposer); + this._composers.set(OutgoingHeader.TRADE_CANCEL, TradingCancelComposer); + this._composers.set(OutgoingHeader.TRADE_CLOSE, TradingCloseComposer); + this._composers.set(OutgoingHeader.TRADE_CONFIRM, TradingConfirmationComposer); + this._composers.set(OutgoingHeader.TRADE_ITEM, TradingListAddItemComposer); + this._composers.set(OutgoingHeader.TRADE_ITEMS, TradingListAddItemsComposer); + this._composers.set(OutgoingHeader.TRADE_ITEM_REMOVE, TradingListItemRemoveComposer); + this._composers.set(OutgoingHeader.TRADE, TradingOpenComposer); + this._composers.set(OutgoingHeader.TRADE_UNACCEPT, TradingUnacceptComposer); + + // ACHIVEMENTS + this._composers.set(OutgoingHeader.ACHIEVEMENT_LIST, RequestAchievementsMessageComposer); + + // PET + this._composers.set(OutgoingHeader.PET_RESPECT, PetRespectComposer); + this._composers.set(OutgoingHeader.PET_INFO, RequestPetInfoComposer); + + // ROOM + this._composers.set(OutgoingHeader.ROOM_CREATE, RoomCreateComposer); + + // ACCESS + this._composers.set(OutgoingHeader.ROOM_ENTER, RoomEnterComposer); + this._composers.set(OutgoingHeader.ROOM_DOORBELL, RoomDoorbellAccessComposer); + + // ACTION + this._composers.set(OutgoingHeader.ROOM_AMBASSADOR_ALERT, RoomAmbassadorAlertComposer); + this._composers.set(OutgoingHeader.ROOM_BAN_GIVE, RoomBanUserComposer); + this._composers.set(OutgoingHeader.ROOM_BAN_REMOVE, RoomUnbanUserComposer); + this._composers.set(OutgoingHeader.ROOM_RIGHTS_GIVE, RoomGiveRightsComposer); + this._composers.set(OutgoingHeader.ROOM_KICK, RoomKickUserComposer); + this._composers.set(OutgoingHeader.ROOM_MUTE_USER, RoomMuteUserComposer); + this._composers.set(OutgoingHeader.ROOM_RIGHTS_REMOVE, RoomTakeRightsComposer); + + this._composers.set(OutgoingHeader.ROOM_LIKE, RoomLikeRoomComposer); + this._composers.set(OutgoingHeader.ROOM_DELETE, RoomDeleteComposer); + this._composers.set(OutgoingHeader.ROOM_STAFF_PICK, RoomStaffPickComposer); + + // DATA + this._composers.set(OutgoingHeader.ROOM_INFO, RoomInfoComposer); + this._composers.set(OutgoingHeader.ROOM_SETTINGS, RoomSettingsComposer); + this._composers.set(OutgoingHeader.ROOM_SETTINGS_SAVE, SaveRoomSettingsComposer); + this._composers.set(OutgoingHeader.ROOM_RIGHTS_LIST, RoomUsersWithRightsComposer); + this._composers.set(OutgoingHeader.ROOM_BAN_LIST, RoomBannedUsersComposer); + + // BOTS + this._composers.set(OutgoingHeader.BOT_CONFIGURATION, RequestBotCommandConfigurationComposer); + + // ENGINE + this._composers.set(OutgoingHeader.GET_ITEM_DATA, GetItemDataComposer); + this._composers.set(OutgoingHeader.REMOVE_WALL_ITEM, RemoveWallItemComposer); + this._composers.set(OutgoingHeader.MODIFY_WALL_ITEM_DATA, ModifyWallItemDataComposer); + this._composers.set(OutgoingHeader.BOT_PLACE, BotPlaceComposer); + this._composers.set(OutgoingHeader.BOT_PICKUP, BotRemoveComposer); + this._composers.set(OutgoingHeader.BOT_SKILL_SAVE, BotSkillSaveComposer); + this._composers.set(OutgoingHeader.PET_PLACE, PetPlaceComposer); + this._composers.set(OutgoingHeader.PET_MOVE, PetMoveComposer); + this._composers.set(OutgoingHeader.PET_PICKUP, PetRemoveComposer); + + // FURNITURE + this._composers.set(OutgoingHeader.FURNITURE_ALIASES, FurnitureAliasesComposer); + this._composers.set(OutgoingHeader.FURNITURE_PICKUP, FurniturePickupComposer); + this._composers.set(OutgoingHeader.FURNITURE_PLACE, FurniturePlaceComposer); + this._composers.set(OutgoingHeader.ITEM_PAINT, FurniturePlacePaintComposer); + this._composers.set(OutgoingHeader.FURNITURE_POSTIT_PLACE, FurniturePostItPlaceComposer); + + // FLOOR + this._composers.set(OutgoingHeader.FURNITURE_FLOOR_UPDATE, FurnitureFloorUpdateComposer); + + // WALL + this._composers.set(OutgoingHeader.FURNITURE_WALL_UPDATE, FurnitureWallUpdateComposer); + + // Dimmers + this._composers.set(OutgoingHeader.ITEM_DIMMER_SETTINGS, MoodlightSettingsComposer); + this._composers.set(OutgoingHeader.ITEM_DIMMER_SAVE, MoodlightSettingsSaveComposer); + this._composers.set(OutgoingHeader.ITEM_DIMMER_TOGGLE, MoodlightTogggleStateComposer); + + // Toners + this._composers.set(OutgoingHeader.ROOM_TONER_APPLY, ApplyTonerComposer); + + // LOGIC + this._composers.set(OutgoingHeader.ITEM_COLOR_WHEEL_CLICK, FurnitureColorWheelComposer); + this._composers.set(OutgoingHeader.ITEM_DICE_CLICK, FurnitureDiceActivateComposer); + this._composers.set(OutgoingHeader.ITEM_DICE_CLOSE, FurnitureDiceDeactivateComposer); + this._composers.set(OutgoingHeader.FURNITURE_MULTISTATE, FurnitureMultiStateComposer); + this._composers.set(OutgoingHeader.FURNITURE_RANDOMSTATE, FurnitureRandomStateComposer); + this._composers.set(OutgoingHeader.ITEM_STACK_HELPER, FurnitureStackHeightComposer); + this._composers.set(OutgoingHeader.FURNITURE_WALL_MULTISTATE, FurnitureWallMultiStateComposer); + this._composers.set(OutgoingHeader.ONE_WAY_DOOR_CLICK, FurnitureOneWayDoorComposer); + this._composers.set(OutgoingHeader.ITEM_EXCHANGE_REDEEM, FurnitureExchangeComposer); + this._composers.set(OutgoingHeader.ITEM_CLOTHING_REDEEM, RedeemItemClothingComposer); + + // MAPPING + this._composers.set(OutgoingHeader.ROOM_MODEL, RoomModelComposer); + + // UNIT + this._composers.set(OutgoingHeader.UNIT_ACTION, RoomUnitActionComposer); + this._composers.set(OutgoingHeader.UNIT_DANCE, RoomUnitDanceComposer); + this._composers.set(OutgoingHeader.UNIT_DROP_HAND_ITEM, RoomUnitDropHandItemComposer); + this._composers.set(OutgoingHeader.UNIT_GIVE_HANDITEM, RoomUnitGiveHandItemComposer); + this._composers.set(OutgoingHeader.UNIT_LOOK, RoomUnitLookComposer); + this._composers.set(OutgoingHeader.UNIT_SIGN, RoomUnitSignComposer); + this._composers.set(OutgoingHeader.UNIT_POSTURE, RoomUnitPostureComposer); + this._composers.set(OutgoingHeader.UNIT_WALK, RoomUnitWalkComposer); + + // CHAT + this._composers.set(OutgoingHeader.UNIT_CHAT, RoomUnitChatComposer); + this._composers.set(OutgoingHeader.UNIT_CHAT_SHOUT, RoomUnitChatShoutComposer); + this._composers.set(OutgoingHeader.USER_SETTINGS_CHAT_STYLE, RoomUnitChatStyleComposer); + this._composers.set(OutgoingHeader.UNIT_CHAT_WHISPER, RoomUnitChatWhisperComposer); + this._composers.set(OutgoingHeader.UNIT_TYPING, RoomUnitTypingStartComposer); + this._composers.set(OutgoingHeader.UNIT_TYPING_STOP, RoomUnitTypingStopComposer); + + // ROOM EVENTS + this._composers.set(OutgoingHeader.WIRED_APPLY_SNAPSHOT, ApplySnapshotMessageComposer); + this._composers.set(OutgoingHeader.WIRED_OPEN, OpenMessageComposer); + this._composers.set(OutgoingHeader.WIRED_ACTION_SAVE, UpdateActionMessageComposer); + this._composers.set(OutgoingHeader.WIRED_CONDITION_SAVE, UpdateConditionMessageComposer); + this._composers.set(OutgoingHeader.WIRED_TRIGGER_SAVE, UpdateTriggerMessageComposer); + this._composers.set(OutgoingHeader.ROOM_MUTE, RoomMuteComposer); + + // USER + this._composers.set(OutgoingHeader.USER_RESPECT, UserRespectComposer); + + // DATA + this._composers.set(OutgoingHeader.USER_IGNORED, GetIgnoredUsersComposer); + this._composers.set(OutgoingHeader.USER_IGNORE, IgnoreUserComposer); + this._composers.set(OutgoingHeader.USER_IGNORE_ID, IgnoreUserIdComposer); + this._composers.set(OutgoingHeader.USER_UNIGNORE, UnignoreUserComposer); + this._composers.set(OutgoingHeader.USER_BADGES_CURRENT, UserCurrentBadgesComposer); + this._composers.set(OutgoingHeader.USER_FIGURE, UserFigureComposer); + this._composers.set(OutgoingHeader.USER_HOME_ROOM, UserHomeRoomComposer); + this._composers.set(OutgoingHeader.USER_MOTTO, UserMottoComposer); + this._composers.set(OutgoingHeader.USER_PROFILE, UserProfileComposer); + this._composers.set(OutgoingHeader.MESSENGER_RELATIONSHIPS, UserRelationshipsComposer); + + // MANNEQUIN + this._composers.set(OutgoingHeader.MANNEQUIN_SAVE_NAME, FurnitureMannequinSaveNameComposer); + this._composers.set(OutgoingHeader.MANNEQUIN_SAVE_LOOK, FurnitureMannequinSaveLookComposer); + + // GIFTS + this._composers.set(OutgoingHeader.PRESENT_OPEN_PRESENT, OpenPresentComposer); + + // INVENTORY + + // BOTS + this._composers.set(OutgoingHeader.USER_BOTS, GetBotInventoryComposer); + + // BADGES + this._composers.set(OutgoingHeader.USER_BADGES, RequestBadgesComposer); + this._composers.set(OutgoingHeader.USER_BADGES_CURRENT_UPDATE, SetActivatedBadgesComposer); + + // PETS + this._composers.set(OutgoingHeader.USER_PETS, RequestPetsComposer); + + // CURRENCY + this._composers.set(OutgoingHeader.USER_CURRENCY, UserCurrencyComposer); + + // SUBSCRIPTION + this._composers.set(OutgoingHeader.USER_SUBSCRIPTION, UserSubscriptionComposer); + + // MODTOOL + this._composers.set(OutgoingHeader.MODTOOL_REQUEST_ROOM_INFO, ModtoolRequestRoomInfoComposer); + this._composers.set(OutgoingHeader.MODTOOL_CHANGE_ROOM_SETTINGS, ModtoolChangeRoomSettingsComposer); + this._composers.set(OutgoingHeader.MODTOOL_REQUEST_USER_CHATLOG, ModtoolRequestUserChatlogComposer); + this._composers.set(OutgoingHeader.MODTOOL_REQUEST_ROOM_CHATLOG, ModtoolRequestRoomChatlogComposer); + this._composers.set(OutgoingHeader.MOD_TOOL_USER_INFO, ModtoolRequestUserInfoComposer); + this._composers.set(OutgoingHeader.MODTOOL_SANCTION_ALERT, ModtoolSanctionAlertComposer); + this._composers.set(OutgoingHeader.MODTOOL_SANCTION_BAN, ModtoolSanctionBanComposer); + this._composers.set(OutgoingHeader.MODTOOL_SANCTION_KICK, ModtoolSanctionKickComposer); + this._composers.set(OutgoingHeader.MODTOOL_SANCTION_TRADELOCK, ModtoolSanctionTradelockComposer); + this._composers.set(OutgoingHeader.MODTOOL_ALERTEVENT, ModtoolEventAlertComposer); + this._composers.set(OutgoingHeader.MODTOOL_SANCTION_MUTE, ModtoolSanctionMuteComposer); + this._composers.set(OutgoingHeader.MODTOOL_REQUEST_USER_ROOMS, ModtoolRequestUserRoomsComposer); + this._composers.set(OutgoingHeader.MODTOOL_ROOM_ALERT, ModtoolRoomAlertComposer); + + // WARDROBE + this._composers.set(OutgoingHeader.USER_WARDROBE_PAGE, UserWardrobePageComposer); + this._composers.set(OutgoingHeader.USER_WARDROBE_SAVE, UserWardrobeSaveComposer); + + // SETTINGS + this._composers.set(OutgoingHeader.USER_SETTINGS_CAMERA, UserSettingsCameraFollowComposer); + this._composers.set(OutgoingHeader.USER_SETTINGS_OLD_CHAT, UserSettingsOldChatComposer); + this._composers.set(OutgoingHeader.USER_SETTINGS_INVITES, UserSettingsRoomInvitesComposer); + this._composers.set(OutgoingHeader.USER_SETTINGS_VOLUME, UserSettingsSoundComposer); + } + + public get events(): Map + { + return this._events; + } + + public get composers(): Map + { + return this._composers; + } +} diff --git a/src/nitro/communication/demo/NitroCommunicationDemo.ts b/src/nitro/communication/demo/NitroCommunicationDemo.ts new file mode 100644 index 00000000..d4cec0a6 --- /dev/null +++ b/src/nitro/communication/demo/NitroCommunicationDemo.ts @@ -0,0 +1,205 @@ +import { NitroLogger } from '../../../core/common/logger/NitroLogger'; +import { NitroManager } from '../../../core/common/NitroManager'; +import { IConnection } from '../../../core/communication/connections/IConnection'; +import { SocketConnectionEvent } from '../../../core/communication/events/SocketConnectionEvent'; +import { Nitro } from '../../Nitro'; +import { INitroCommunicationManager } from '../INitroCommunicationManager'; +import { ClientPingEvent } from '../messages/incoming/client/ClientPingEvent'; +import { AuthenticatedEvent } from '../messages/incoming/security/AuthenticatedEvent'; +import { ClientPongComposer } from '../messages/outgoing/client/ClientPongComposer'; +import { ClientReleaseVersionComposer } from '../messages/outgoing/client/ClientReleaseVersionComposer'; +import { InfoRetrieveBaseMessageComposer } from '../messages/outgoing/handshake/InfoRetrieveBaseMessageComposer'; +import { SecurityTicketComposer } from '../messages/outgoing/handshake/SecurityTicketComposer'; +import { NitroCommunicationDemoEvent } from './NitroCommunicationDemoEvent'; + +export class NitroCommunicationDemo extends NitroManager +{ + private _communication: INitroCommunicationManager; + + private _sso: string; + private _handShaking: boolean; + private _didConnect: boolean; + + private _pongInterval: any; + + constructor(communication: INitroCommunicationManager) + { + super(); + + this._communication = communication; + + this._sso = null; + this._handShaking = false; + this._didConnect = false; + + this._pongInterval = null; + + this.onConnectionOpenedEvent = this.onConnectionOpenedEvent.bind(this); + this.onConnectionClosedEvent = this.onConnectionClosedEvent.bind(this); + this.onConnectionErrorEvent = this.onConnectionErrorEvent.bind(this); + this.sendPong = this.sendPong.bind(this); + } + + protected onInit(): void + { + const connection = this._communication.connection; + + if(connection) + { + connection.addEventListener(SocketConnectionEvent.CONNECTION_OPENED, this.onConnectionOpenedEvent); + connection.addEventListener(SocketConnectionEvent.CONNECTION_CLOSED, this.onConnectionClosedEvent); + connection.addEventListener(SocketConnectionEvent.CONNECTION_ERROR, this.onConnectionErrorEvent); + } + + this._communication.registerMessageEvent(new ClientPingEvent(this.onClientPingEvent.bind(this))); + this._communication.registerMessageEvent(new AuthenticatedEvent(this.onAuthenticatedEvent.bind(this))); + } + + protected onDispose(): void + { + const connection = this._communication.connection; + + if(connection) + { + connection.removeEventListener(SocketConnectionEvent.CONNECTION_OPENED, this.onConnectionOpenedEvent); + connection.removeEventListener(SocketConnectionEvent.CONNECTION_CLOSED, this.onConnectionClosedEvent); + connection.removeEventListener(SocketConnectionEvent.CONNECTION_ERROR, this.onConnectionErrorEvent); + } + + this._sso = null; + this._handShaking = false; + + this.stopPonging(); + + super.onDispose(); + } + + private onConnectionOpenedEvent(event: Event): void + { + const connection = this._communication.connection; + + if(!connection) return; + + this._didConnect = true; + + this.dispatchCommunicationDemoEvent(NitroCommunicationDemoEvent.CONNECTION_ESTABLISHED, connection); + + if(Nitro.instance.getConfiguration('communication.pong.manually', false)) this.startPonging(); + + this.startHandshake(connection); + + connection.send(new ClientReleaseVersionComposer(null, null, null, null)); + + this.tryAuthentication(connection); + } + + private onConnectionClosedEvent(event: CloseEvent): void + { + const connection = this._communication.connection; + + if(!connection) return; + + this.stopPonging(); + + if(this._didConnect) this.dispatchCommunicationDemoEvent(NitroCommunicationDemoEvent.CONNECTION_CLOSED, connection); + } + + private onConnectionErrorEvent(event: CloseEvent): void + { + const connection = this._communication.connection; + + if(!connection) return; + + this.stopPonging(); + + this.dispatchCommunicationDemoEvent(NitroCommunicationDemoEvent.CONNECTION_ERROR, connection); + } + + private tryAuthentication(connection: IConnection): void + { + if(!connection || !this._sso) + { + if(!this._sso) + { + NitroLogger.log('Login without an SSO ticket is not supported'); + } + + this.dispatchCommunicationDemoEvent(NitroCommunicationDemoEvent.CONNECTION_HANDSHAKE_FAILED, connection); + + return; + } + + connection.send(new SecurityTicketComposer(this._sso, Nitro.instance.time)); + } + + private onClientPingEvent(event: ClientPingEvent): void + { + if(!event || !event.connection) return; + + this.sendPong(event.connection); + } + + private onAuthenticatedEvent(event: AuthenticatedEvent): void + { + if(!event || !event.connection) return; + + this.completeHandshake(event.connection); + + this.dispatchCommunicationDemoEvent(NitroCommunicationDemoEvent.CONNECTION_AUTHENTICATED, event.connection); + + //event.connection.send(new UserHomeRoomComposer(555)); + + event.connection.send(new InfoRetrieveBaseMessageComposer()); + } + + public setSSO(sso: string): void + { + if(!sso || (sso === '') || this._sso) return; + + this._sso = sso; + } + + private startHandshake(connection: IConnection): void + { + this.dispatchCommunicationDemoEvent(NitroCommunicationDemoEvent.CONNECTION_HANDSHAKING, connection); + + this._handShaking = true; + } + + private completeHandshake(connection: IConnection): void + { + this.dispatchCommunicationDemoEvent(NitroCommunicationDemoEvent.CONNECTION_HANDSHAKED, connection); + + this._handShaking = false; + } + + private startPonging(): void + { + this.stopPonging(); + + this._pongInterval = setInterval(this.sendPong, Nitro.instance.getConfiguration('communication.pong.interval.ms', 20000)); + } + + private stopPonging(): void + { + if(!this._pongInterval) return; + + clearInterval(this._pongInterval); + + this._pongInterval = null; + } + + private sendPong(connection: IConnection = null): void + { + connection = ((connection || this._communication.connection) || null); + + if(!connection) return; + + connection.send(new ClientPongComposer()); + } + + private dispatchCommunicationDemoEvent(type: string, connection: IConnection): void + { + Nitro.instance.events.dispatchEvent(new NitroCommunicationDemoEvent(type, connection)); + } +} diff --git a/src/nitro/communication/demo/NitroCommunicationDemoEvent.ts b/src/nitro/communication/demo/NitroCommunicationDemoEvent.ts new file mode 100644 index 00000000..43ff9df1 --- /dev/null +++ b/src/nitro/communication/demo/NitroCommunicationDemoEvent.ts @@ -0,0 +1,27 @@ +import { IConnection } from '../../../core/communication/connections/IConnection'; +import { NitroEvent } from '../../../core/events/NitroEvent'; + +export class NitroCommunicationDemoEvent extends NitroEvent +{ + public static CONNECTION_ESTABLISHED = 'NCE_ESTABLISHED'; + public static CONNECTION_CLOSED = 'NCE_CLOSED'; + public static CONNECTION_ERROR = 'NCE_ERROR'; + public static CONNECTION_HANDSHAKING = 'NCE_HANDSHAKING'; + public static CONNECTION_HANDSHAKED = 'NCE_HANDSHAKED'; + public static CONNECTION_HANDSHAKE_FAILED = 'NCE_HANDSHAKE_FAILED'; + public static CONNECTION_AUTHENTICATED = 'NCE_AUTHENTICATED'; + + private _connection: IConnection; + + constructor(type: string, connection: IConnection) + { + super(type); + + this._connection = connection; + } + + public get connection(): IConnection + { + return this._connection; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/IncomingHeader.ts b/src/nitro/communication/messages/incoming/IncomingHeader.ts new file mode 100644 index 00000000..4b16db9b --- /dev/null +++ b/src/nitro/communication/messages/incoming/IncomingHeader.ts @@ -0,0 +1,241 @@ +export class IncomingHeader +{ + public static ACHIEVEMENT_LIST = 305; + public static AUTHENTICATED = 2491; + public static AVAILABILITY_STATUS = 2033; + public static BUILDERS_CLUB_EXPIRED = 1452; + public static CAMERA_PRICE = 3878; + public static CAMERA_THUMBNAIL_SAVED = 3595; + public static CAMERA_URL = 3696; + public static CATALOG_CLUB = 2405; + public static CATALOG_MODE = 3828; + public static CATALOG_PAGE = 804; + public static CATALOG_PAGES = 1032; + public static CATALOG_PURCHASE = 869; + public static CATALOG_PURCHASE_FAILED = 1404; + public static CATALOG_PURCHASE_UNAVAILABLE = 3770; + public static CATALOG_SEARCH = 3388; + public static CATALOG_SOLD_OUT = 377; + public static CATALOG_UPDATED = 1866; + public static CFH_RESULT_MESSAGE = 934; + public static CLIENT_LATENCY = 10; + public static CLIENT_PING = 3928; + public static DESKTOP_CAMPAIGN = 1745; + public static DESKTOP_NEWS = 286; + public static DESKTOP_VIEW = 122; + public static DISCOUNT_CONFIG = 2347; + public static FIRST_LOGIN_OF_DAY = 793; + public static FURNITURE_ALIASES = 1723; + public static FURNITURE_DATA = 2547; + public static FURNITURE_FLOOR = 1778; + public static FURNITURE_FLOOR_ADD = 1534; + public static FURNITURE_FLOOR_REMOVE = 2703; + public static FURNITURE_FLOOR_UPDATE = 3776; + public static FURNITURE_ITEMDATA = 2202; + public static FURNITURE_STATE = 2376; + public static GAME_CENTER_ACHIEVEMENTS = 2265; + public static GAME_CENTER_GAME_LIST = 222; + public static GAME_CENTER_STATUS = 2893; + public static GENERIC_ALERT = 3801; + public static GENERIC_ALERT_LINK = 2030; + public static GENERIC_ERROR = 1600; + public static GIFT_CONFIG = 2234; + public static GROUP_BADGES = 2402; + public static GROUP_CREATE_OPTIONS = 2159; + public static GROUP_FORUM_INFO = 3011; + public static GROUP_FORUM_LIST = 3001; + public static GROUP_FORUM_THREADS = 1073; + public static GROUP_INFO = 1702; + public static GROUP_LIST = 420; + public static GROUP_MEMBER = 265; + public static GROUP_MEMBERS = 1200; + public static GROUP_MEMBERS_REFRESH = 2445; + public static GROUP_MEMBER_REMOVE_CONFIRM = 1876; + public static GROUP_SETTINGS = 3965; + public static GROUP_BADGE_PARTS = 2238; + public static ITEM_DIMMER_SETTINGS = 2710; + public static ITEM_STACK_HELPER = 2816; + public static ITEM_WALL = 1369; + public static ITEM_WALL_ADD = 2187; + public static ITEM_WALL_REMOVE = 3208; + public static ITEM_WALL_UPDATE = 2009; + public static LOAD_GAME_URL = 2624; + public static MARKETPLACE_CONFIG = 1823; + public static MESSENGER_ACCEPT_FRIENDS = 896; + public static MESSENGER_CHAT = 1587; + public static MESSENGER_FIND_FRIENDS = 1210; + public static MESSENGER_FOLLOW_FAILED = 3048; + public static MESSENGER_FRIEND_NOTIFICATION = 3082; + public static MESSENGER_FRIENDS = 3130; + public static MESSENGER_INIT = 1605; + public static MESSENGER_INSTANCE_MESSAGE_ERROR = 3359; + public static MESSENGER_INVITE = 3870; + public static MESSENGER_INVITE_ERROR = 462; + public static MESSENGER_MESSAGE_ERROR = 892; + public static MESSENGER_MINIMAIL_COUNT = 2803; + public static MESSENGER_MINIMAIL_NEW = 1911; + public static MESSENGER_RELATIONSHIPS = 2016; + public static MESSENGER_REQUEST = 2219; + public static MESSENGER_REQUEST_ERROR = 892; + public static MESSENGER_REQUESTS = 280; + public static MESSENGER_ROOM_INVITE = 3870; + public static MESSENGER_SEARCH = 973; + public static MESSENGER_UPDATE = 2800; + public static MODERATION_REPORT_DISABLED = 1651; + public static MODERATION_TOOL = 2696; + public static MODERATION_TOPICS = 325; + public static MODERATION_USER_INFO = 2866; + public static MOTD_MESSAGES = 2035; + public static NAVIGATOR_CATEGORIES = 1562; + public static NAVIGATOR_COLLAPSED = 1543; + public static NAVIGATOR_EVENT_CATEGORIES = 3244; + public static NAVIGATOR_LIFTED = 3104; + public static NAVIGATOR_METADATA = 3052; + public static NAVIGATOR_OPEN_ROOM_CREATOR = 2064; + public static NAVIGATOR_SEARCH = 2690; + public static NAVIGATOR_SEARCHES = 3984; + public static NAVIGATOR_SETTINGS = 518; + public static NOTIFICATION_LIST = 1992; + public static PET_FIGURE_UPDATE = 1924; + public static PET_INFO = 2901; + public static RECYCLER_PRIZES = 3164; + public static ROOM_BAN_LIST = 1869; + public static ROOM_BAN_REMOVE = 3429; + public static ROOM_CREATED = 1304; + public static ROOM_DOORBELL = 2309; + public static ROOM_DOORBELL_ACCEPTED = 3783; + public static ROOM_DOORBELL_REJECTED = 878; + public static ROOM_ENTER = 758; + public static ROOM_ENTER_ERROR = 899; + public static ROOM_FORWARD = 160; + public static ROOM_HEIGHT_MAP = 2753; + public static ROOM_HEIGHT_MAP_UPDATE = 558; + public static ROOM_INFO = 687; + public static ROOM_INFO_OWNER = 749; + public static ROOM_MODEL = 1301; + public static ROOM_MODEL_BLOCKED_TILES = 3990; + public static ROOM_MODEL_DOOR = 1664; + public static ROOM_MODEL_NAME = 2031; + public static ROOM_MUTED = 2533; + public static ROOM_MUTE_USER = 826; + public static ROOM_PAINT = 2454; + public static ROOM_PROMOTION = 2274; + public static ROOM_QUEUE_STATUS = 2208; + public static ROOM_RIGHTS = 780; + public static ROOM_RIGHTS_CLEAR = 2392; + public static ROOM_RIGHTS_LIST = 1284; + public static ROOM_RIGHTS_LIST_ADD = 2088; + public static ROOM_RIGHTS_LIST_REMOVE = 1327; + public static ROOM_RIGHTS_OWNER = 339; + public static ROOM_ROLLING = 3207; + public static ROOM_SCORE = 482; + public static ROOM_SETTINGS = 1498; + public static ROOM_SETTINGS_CHAT = 1191; + public static ROOM_SETTINGS_SAVE = 948; + public static ROOM_SETTINGS_SAVE_ERROR = 1555; + public static ROOM_SETTINGS_UPDATED = 3297; + public static ROOM_SPECTATOR = 1033; + public static ROOM_THICKNESS = 3547; + public static SECURITY_DEBUG = 3284; + public static SECURITY_MACHINE = 1488; + public static SECURITY_UNKNOWN2 = 2833; + public static TRADE_ACCEPTED = 2568; + public static TRADE_CLOSED = 1373; + public static TRADE_COMPLETED = 1001; + public static TRADE_CONFIRMATION = 2720; + public static TRADE_LIST_ITEM = 2024; + public static TRADE_NOT_OPEN = 3128; + public static TRADE_OPEN = 2505; + public static TRADE_OPEN_FAILED = 217; + public static TRADE_OTHER_NOT_ALLOWED = 2154; + public static TRADE_YOU_NOT_ALLOWED = 3058; + public static UNIT = 374; + public static UNIT_CHANGE_NAME = 2182; + public static UNIT_CHAT = 1446; + public static UNIT_CHAT_SHOUT = 1036; + public static UNIT_CHAT_WHISPER = 2704; + public static UNIT_DANCE = 2233; + public static UNIT_EFFECT = 1167; + public static UNIT_EXPRESSION = 1631; + public static UNIT_HAND_ITEM = 1474; + public static UNIT_IDLE = 1797; + public static UNIT_INFO = 3920; + public static UNIT_NUMBER = 2324; + public static UNIT_REMOVE = 2661; + public static UNIT_STATUS = 1640; + public static UNIT_TYPING = 1717; + public static UNSEEN_ITEMS = 2103; + public static USER_ACHIEVEMENT_SCORE = 1968; + public static USER_BADGES = 717; + public static USER_BADGES_ADD = 2493; + public static USER_BADGES_CURRENT = 1087; + public static USER_BOT_ADD = 1352; + public static USER_BOT_REMOVE = 233; + public static USER_BOTS = 3086; + public static USER_CHANGE_NAME = 118; + public static USER_CLOTHING = 1450; + public static USER_CREDITS = 3475; + public static USER_CURRENCY = 2018; + public static USER_CURRENCY_UPDATE = 2275; + public static USER_EFFECTS = 340; + public static USER_FAVORITE_ROOM = 2524; + public static USER_FAVORITE_ROOM_COUNT = 151; + public static USER_FIGURE = 2429; + public static USER_FURNITURE = 994; + public static USER_FURNITURE_ADD = 104; + public static USER_FURNITURE_POSTIT_PLACED = 1501; + public static USER_FURNITURE_REFRESH = 3151; + public static USER_FURNITURE_REMOVE = 159; + public static USER_HOME_ROOM = 2875; + public static USER_IGNORED = 126; + public static USER_IGNORED_RESULT = 207; + public static USER_INFO = 2725; + public static USER_OUTFITS = 3315; + public static USER_PERKS = 2586; + public static USER_PERMISSIONS = 411; + public static USER_PET_ADD = 2101; + public static USER_PET_REMOVE = 3253; + public static USER_PETS = 3522; + public static USER_PROFILE = 3898; + public static USER_RESPECT = 2815; + public static USER_SANCTION_STATUS = 3679; + public static USER_SETTINGS = 513; + public static USER_SUBSCRIPTION = 954; + public static USER_WARDROBE_PAGE = 3315; + public static WIRED_ACTION = 1434; + public static WIRED_CONDITION = 1108; + public static WIRED_ERROR = 156; + public static WIRED_OPEN = 1830; + public static WIRED_REWARD = 178; + public static WIRED_SAVE = 1155; + public static WIRED_TRIGGER = 383; + public static PLAYING_GAME = 448; + public static FURNITURE_STATE_2 = 3431; + public static REMOVE_BOT_FROM_INVENTORY = 233; + public static ADD_BOT_TO_INVENTORY = 1352; + public static ACHIEVEMENT_PROGRESSED = 2107; + public static MODTOOL_ROOM_INFO = 1333; + public static MODTOOL_USER_CHATLOG = 3377; + public static MODTOOL_ROOM_CHATLOG = 3434; + public static LOVELOCK_FURNI_START = 3753; + public static LOVELOCK_FURNI_FRIEND_COMFIRMED = 382; + public static LOVELOCK_FURNI_FINISHED = 770; + public static GIFT_RECEIVER_NOT_FOUND = 1517; + public static GIFT_OPENED = 56; + public static HOTEL_WILL_SHUTDOWN = 1050; + public static FLOOD_CONTROL = 566; + public static REMAINING_MUTE = 826; + public static USER_EFFECT_LIST = 340; + public static USER_EFFECT_LIST_ADD = 2867; + public static USER_EFFECT_LIST_REMOVE = 2228; + public static USER_EFFECT_ACTIVATE = 1959; + public static CATALOG_CLUB_GIFTS = 619; + public static REDEEM_VOUCHER_ERROR = 714; + public static REDEEM_VOUCHER_OK = 3336; + public static MODTOOL_VISITED_ROOMS_USER = 1752; + public static IN_CLIENT_LINK = 2023; + public static BOT_COMMAND_CONFIGURATION = 1618; + public static HAND_ITEM_RECEIVED = 354; + public static PET_PLACING_ERROR = 2913; + public static BOT_ERROR = 639; +} diff --git a/src/nitro/communication/messages/incoming/availability/AvailabilityStatusMessageEvent.ts b/src/nitro/communication/messages/incoming/availability/AvailabilityStatusMessageEvent.ts new file mode 100644 index 00000000..8d1cfa30 --- /dev/null +++ b/src/nitro/communication/messages/incoming/availability/AvailabilityStatusMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { AvailabilityStatusMessageParser } from '../../parser/availability/AvailabilityStatusMessageParser'; + +export class AvailabilityStatusMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, AvailabilityStatusMessageParser); + } + + public getParser(): AvailabilityStatusMessageParser + { + return this.parser as AvailabilityStatusMessageParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/avatar/ChangeNameUpdateEvent.ts b/src/nitro/communication/messages/incoming/avatar/ChangeNameUpdateEvent.ts new file mode 100644 index 00000000..e31aaa32 --- /dev/null +++ b/src/nitro/communication/messages/incoming/avatar/ChangeNameUpdateEvent.ts @@ -0,0 +1,25 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { ChangeNameUpdateParser } from '../../parser/avatar/ChangeNameUpdateParser'; + +export class ChangeNameUpdateEvent extends MessageEvent implements IMessageEvent +{ + public static _Str_5797: number = 0; + public static _Str_7005: number = 1; + public static _Str_7389: number = 2; + public static _Str_7137: number = 3; + public static _Str_7836: number = 4; + public static _Str_7721: number = 5; + public static _Str_8620: number = 6; + public static _Str_9429: number = 7; + + constructor(callBack: Function) + { + super(callBack, ChangeNameUpdateParser); + } + + public getParser(): ChangeNameUpdateParser + { + return this.parser as ChangeNameUpdateParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/catalog/CatalogClubEvent.ts b/src/nitro/communication/messages/incoming/catalog/CatalogClubEvent.ts new file mode 100644 index 00000000..ec0ddb82 --- /dev/null +++ b/src/nitro/communication/messages/incoming/catalog/CatalogClubEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { CatalogClubParser } from '../../parser/catalog/CatalogClubParser'; + +export class CatalogClubEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, CatalogClubParser); + } + + public getParser(): CatalogClubParser + { + return this.parser as CatalogClubParser; + } +} diff --git a/src/nitro/communication/messages/incoming/catalog/CatalogClubGiftsEvent.ts b/src/nitro/communication/messages/incoming/catalog/CatalogClubGiftsEvent.ts new file mode 100644 index 00000000..29ae3bf7 --- /dev/null +++ b/src/nitro/communication/messages/incoming/catalog/CatalogClubGiftsEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { CatalogClubGiftsParser } from '../../parser/catalog/CatalogClubGiftsParser'; + +export class CatalogClubGiftsEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, CatalogClubGiftsParser); + } + + public getParser(): CatalogClubGiftsParser + { + return this.parser as CatalogClubGiftsParser; + } +} diff --git a/src/nitro/communication/messages/incoming/catalog/CatalogGiftConfigurationEvent.ts b/src/nitro/communication/messages/incoming/catalog/CatalogGiftConfigurationEvent.ts new file mode 100644 index 00000000..a7a9f47c --- /dev/null +++ b/src/nitro/communication/messages/incoming/catalog/CatalogGiftConfigurationEvent.ts @@ -0,0 +1,17 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { CatalogPagesParser } from '../../parser/catalog/CatalogPagesParser'; +import { CatalogGiftConfigurationParser } from '../../parser/catalog/CatalogGiftConfigurationParser'; + +export class CatalogGiftConfigurationEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, CatalogGiftConfigurationParser); + } + + public getParser(): CatalogGiftConfigurationParser + { + return this.parser as CatalogGiftConfigurationParser; + } +} diff --git a/src/nitro/communication/messages/incoming/catalog/CatalogGiftUsernameUnavailableEvent.ts b/src/nitro/communication/messages/incoming/catalog/CatalogGiftUsernameUnavailableEvent.ts new file mode 100644 index 00000000..f6b565e8 --- /dev/null +++ b/src/nitro/communication/messages/incoming/catalog/CatalogGiftUsernameUnavailableEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { CatalogGiftUsernameUnavailableParser } from '../../parser/catalog/CatalogGiftUsernameUnavailableParser'; + +export class CatalogGiftUsernameUnavailableEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, CatalogGiftUsernameUnavailableParser); + } + + public getParser(): CatalogGiftUsernameUnavailableParser + { + return this.parser as CatalogGiftUsernameUnavailableParser; + } +} diff --git a/src/nitro/communication/messages/incoming/catalog/CatalogGroupsEvent.ts b/src/nitro/communication/messages/incoming/catalog/CatalogGroupsEvent.ts new file mode 100644 index 00000000..aa0234d7 --- /dev/null +++ b/src/nitro/communication/messages/incoming/catalog/CatalogGroupsEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { CatalogGroupsParser } from '../../parser/catalog/CatalogGroupsParser'; + +export class CatalogGroupsEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, CatalogGroupsParser); + } + + public getParser(): CatalogGroupsParser + { + return this.parser as CatalogGroupsParser; + } +} diff --git a/src/nitro/communication/messages/incoming/catalog/CatalogModeEvent.ts b/src/nitro/communication/messages/incoming/catalog/CatalogModeEvent.ts new file mode 100644 index 00000000..fb76a8a8 --- /dev/null +++ b/src/nitro/communication/messages/incoming/catalog/CatalogModeEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { CatalogModeParser } from '../../parser/catalog/CatalogModeParser'; + +export class CatalogModeEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, CatalogModeParser); + } + + public getParser(): CatalogModeParser + { + return this.parser as CatalogModeParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/catalog/CatalogPageEvent.ts b/src/nitro/communication/messages/incoming/catalog/CatalogPageEvent.ts new file mode 100644 index 00000000..85589423 --- /dev/null +++ b/src/nitro/communication/messages/incoming/catalog/CatalogPageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { CatalogPageParser } from '../../parser/catalog/CatalogPageParser'; + +export class CatalogPageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, CatalogPageParser); + } + + public getParser(): CatalogPageParser + { + return this.parser as CatalogPageParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/catalog/CatalogPagesEvent.ts b/src/nitro/communication/messages/incoming/catalog/CatalogPagesEvent.ts new file mode 100644 index 00000000..a9224d50 --- /dev/null +++ b/src/nitro/communication/messages/incoming/catalog/CatalogPagesEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { CatalogPagesParser } from '../../parser/catalog/CatalogPagesParser'; + +export class CatalogPagesEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, CatalogPagesParser); + } + + public getParser(): CatalogPagesParser + { + return this.parser as CatalogPagesParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/catalog/CatalogPurchaseEvent.ts b/src/nitro/communication/messages/incoming/catalog/CatalogPurchaseEvent.ts new file mode 100644 index 00000000..13711625 --- /dev/null +++ b/src/nitro/communication/messages/incoming/catalog/CatalogPurchaseEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { CatalogPurchaseParser } from '../../parser/catalog/CatalogPurchaseParser'; + +export class CatalogPurchaseEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, CatalogPurchaseParser); + } + + public getParser(): CatalogPurchaseParser + { + return this.parser as CatalogPurchaseParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/catalog/CatalogPurchaseFailedEvent.ts b/src/nitro/communication/messages/incoming/catalog/CatalogPurchaseFailedEvent.ts new file mode 100644 index 00000000..37ae8047 --- /dev/null +++ b/src/nitro/communication/messages/incoming/catalog/CatalogPurchaseFailedEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { CatalogPurchaseFailedParser } from '../../parser/catalog/CatalogPurchaseFailedParser'; + +export class CatalogPurchaseFailedEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, CatalogPurchaseFailedParser); + } + + public getParser(): CatalogPurchaseFailedParser + { + return this.parser as CatalogPurchaseFailedParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/catalog/CatalogPurchaseUnavailableEvent.ts b/src/nitro/communication/messages/incoming/catalog/CatalogPurchaseUnavailableEvent.ts new file mode 100644 index 00000000..5e5555e3 --- /dev/null +++ b/src/nitro/communication/messages/incoming/catalog/CatalogPurchaseUnavailableEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { CatalogPurchaseUnavailableParser } from '../../parser/catalog/CatalogPurchaseUnavailableParser'; + +export class CatalogPurchaseUnavailableEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, CatalogPurchaseUnavailableParser); + } + + public getParser(): CatalogPurchaseUnavailableParser + { + return this.parser as CatalogPurchaseUnavailableParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/catalog/CatalogRedeemVoucherErrorEvent.ts b/src/nitro/communication/messages/incoming/catalog/CatalogRedeemVoucherErrorEvent.ts new file mode 100644 index 00000000..953d9ff9 --- /dev/null +++ b/src/nitro/communication/messages/incoming/catalog/CatalogRedeemVoucherErrorEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { CatalogRedeemVoucherErrorParser } from '../../parser/catalog/CatalogRedeemVoucherErrorParser'; + +export class CatalogRedeemVoucherErrorEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, CatalogRedeemVoucherErrorParser); + } + + public getParser(): CatalogRedeemVoucherErrorParser + { + return this.parser as CatalogRedeemVoucherErrorParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/catalog/CatalogRedeemVoucherOkEvent.ts b/src/nitro/communication/messages/incoming/catalog/CatalogRedeemVoucherOkEvent.ts new file mode 100644 index 00000000..b97bc8a0 --- /dev/null +++ b/src/nitro/communication/messages/incoming/catalog/CatalogRedeemVoucherOkEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { CatalogRedeemVoucherOkParser } from '../../parser/catalog/CatalogRedeemVoucherOkParser'; + +export class CatalogRedeemVoucherOkEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, CatalogRedeemVoucherOkParser); + } + + public getParser(): CatalogRedeemVoucherOkParser + { + return this.parser as CatalogRedeemVoucherOkParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/catalog/CatalogSearchEvent.ts b/src/nitro/communication/messages/incoming/catalog/CatalogSearchEvent.ts new file mode 100644 index 00000000..0e230478 --- /dev/null +++ b/src/nitro/communication/messages/incoming/catalog/CatalogSearchEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { CatalogSearchParser } from '../../parser/catalog/CatalogSearchParser'; + +export class CatalogSearchEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, CatalogSearchParser); + } + + public getParser(): CatalogSearchParser + { + return this.parser as CatalogSearchParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/catalog/CatalogSoldOutEvent.ts b/src/nitro/communication/messages/incoming/catalog/CatalogSoldOutEvent.ts new file mode 100644 index 00000000..96ea0457 --- /dev/null +++ b/src/nitro/communication/messages/incoming/catalog/CatalogSoldOutEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { CatalogSoldOutParser } from '../../parser/catalog/CatalogSoldOutParser'; + +export class CatalogSoldOutEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, CatalogSoldOutParser); + } + + public getParser(): CatalogSoldOutParser + { + return this.parser as CatalogSoldOutParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/catalog/CatalogUpdatedEvent.ts b/src/nitro/communication/messages/incoming/catalog/CatalogUpdatedEvent.ts new file mode 100644 index 00000000..3ee3503b --- /dev/null +++ b/src/nitro/communication/messages/incoming/catalog/CatalogUpdatedEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { CatalogUpdatedParser } from '../../parser/catalog/CatalogUpdatedParser'; + +export class CatalogUpdatedEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, CatalogUpdatedParser); + } + + public getParser(): CatalogUpdatedParser + { + return this.parser as CatalogUpdatedParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/client/ClientPingEvent.ts b/src/nitro/communication/messages/incoming/client/ClientPingEvent.ts new file mode 100644 index 00000000..be283ebd --- /dev/null +++ b/src/nitro/communication/messages/incoming/client/ClientPingEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { ClientPingParser } from '../../parser/client/ClientPingParser'; + +export class ClientPingEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, ClientPingParser); + } + + public getParser(): ClientPingParser + { + return this.parser as ClientPingParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/desktop/DesktopViewEvent.ts b/src/nitro/communication/messages/incoming/desktop/DesktopViewEvent.ts new file mode 100644 index 00000000..869ee120 --- /dev/null +++ b/src/nitro/communication/messages/incoming/desktop/DesktopViewEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { DesktopViewParser } from '../../parser/desktop/DesktopViewParser'; + +export class DesktopViewEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, DesktopViewParser); + } + + public getParser(): DesktopViewParser + { + return this.parser as DesktopViewParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/friendlist/AcceptFriendFailureData.ts b/src/nitro/communication/messages/incoming/friendlist/AcceptFriendFailureData.ts new file mode 100644 index 00000000..c83053e1 --- /dev/null +++ b/src/nitro/communication/messages/incoming/friendlist/AcceptFriendFailureData.ts @@ -0,0 +1,25 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; + +export class AcceptFriendFailerData +{ + private _senderId: number; + private _errorCode: number; + + constructor(wrapper: IMessageDataWrapper) + { + if(!wrapper) throw new Error('invalid_wrapper'); + + this._senderId = wrapper.readInt(); + this._errorCode = wrapper.readInt(); + } + + public get senderId(): number + { + return this._senderId; + } + + public get errorCode(): number + { + return this._errorCode; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/friendlist/AcceptFriendResultEvent.ts b/src/nitro/communication/messages/incoming/friendlist/AcceptFriendResultEvent.ts new file mode 100644 index 00000000..e9e28715 --- /dev/null +++ b/src/nitro/communication/messages/incoming/friendlist/AcceptFriendResultEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { AcceptFriendResultParser } from '../../parser/friendlist/AcceptFriendResultParser'; + +export class AcceptFriendResultEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, AcceptFriendResultParser); + } + + public getParser(): AcceptFriendResultParser + { + return this.parser as AcceptFriendResultParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/friendlist/FindFriendsProcessResultEvent.ts b/src/nitro/communication/messages/incoming/friendlist/FindFriendsProcessResultEvent.ts new file mode 100644 index 00000000..c326b76d --- /dev/null +++ b/src/nitro/communication/messages/incoming/friendlist/FindFriendsProcessResultEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { FindFriendsProcessResultParser } from '../../parser/friendlist/FindFriendsProcessResultParser'; + +export class FindFriendsProcessResultEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FindFriendsProcessResultParser); + } + + public getParser(): FindFriendsProcessResultParser + { + return this.parser as FindFriendsProcessResultParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/friendlist/FollowFriendFailedEvent.ts b/src/nitro/communication/messages/incoming/friendlist/FollowFriendFailedEvent.ts new file mode 100644 index 00000000..0cf9733a --- /dev/null +++ b/src/nitro/communication/messages/incoming/friendlist/FollowFriendFailedEvent.ts @@ -0,0 +1,17 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { DesktopViewParser } from '../../parser/desktop/DesktopViewParser'; +import { FollowFriendFailedParser } from '../../parser/friendlist/FollowFriendFailedParser'; + +export class FollowFriendFailedEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FollowFriendFailedParser); + } + + public getParser(): DesktopViewParser + { + return this.parser as FollowFriendFailedParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/friendlist/FriendCategoryData.ts b/src/nitro/communication/messages/incoming/friendlist/FriendCategoryData.ts new file mode 100644 index 00000000..acd36270 --- /dev/null +++ b/src/nitro/communication/messages/incoming/friendlist/FriendCategoryData.ts @@ -0,0 +1,25 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; + +export class FriendCategoryData +{ + private _id: number; + private _name: string; + + constructor(wrapper: IMessageDataWrapper) + { + if(!wrapper) throw new Error('invalid_wrapper'); + + this._id = wrapper.readInt(); + this._name = wrapper.readString(); + } + + public get id(): number + { + return this._id; + } + + public get name(): string + { + return this._name; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/friendlist/FriendListFragmentEvent.ts b/src/nitro/communication/messages/incoming/friendlist/FriendListFragmentEvent.ts new file mode 100644 index 00000000..3889078c --- /dev/null +++ b/src/nitro/communication/messages/incoming/friendlist/FriendListFragmentEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { FriendListFragmentParser } from '../../parser/friendlist/FriendListFragmentMessageParser'; + +export class FriendListFragmentEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FriendListFragmentParser); + } + + public getParser(): FriendListFragmentParser + { + return this.parser as FriendListFragmentParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/friendlist/FriendListUpdateEvent.ts b/src/nitro/communication/messages/incoming/friendlist/FriendListUpdateEvent.ts new file mode 100644 index 00000000..74caa2ff --- /dev/null +++ b/src/nitro/communication/messages/incoming/friendlist/FriendListUpdateEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { FriendListUpdateParser } from '../../parser/friendlist/FriendListUpdateParser'; + +export class FriendListUpdateEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FriendListUpdateParser); + } + + public getParser(): FriendListUpdateParser + { + return this.parser as FriendListUpdateParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/friendlist/FriendNotificationEvent.ts b/src/nitro/communication/messages/incoming/friendlist/FriendNotificationEvent.ts new file mode 100644 index 00000000..8fd10195 --- /dev/null +++ b/src/nitro/communication/messages/incoming/friendlist/FriendNotificationEvent.ts @@ -0,0 +1,17 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { DesktopViewParser } from '../../parser/desktop/DesktopViewParser'; +import { FriendNotificationParser } from '../../parser/friendlist/FriendNotificationParser'; + +export class FriendNotificationEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FriendNotificationParser); + } + + public getParser(): DesktopViewParser + { + return this.parser as FriendNotificationParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/friendlist/FriendParser.ts b/src/nitro/communication/messages/incoming/friendlist/FriendParser.ts new file mode 100644 index 00000000..11fb9bcd --- /dev/null +++ b/src/nitro/communication/messages/incoming/friendlist/FriendParser.ts @@ -0,0 +1,109 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; + +export class FriendParser +{ + private _id: number; + private _name: string; + private _gender: number; + private _online: boolean; + private _followingAllowed: boolean; + private _figure: string; + private _categoryId: number; + private _motto: string; + private _realName: string; + private _lastAccess: string; + private _persistedMessageUser: boolean; + private _vipMember: boolean; + private _pocketHabboUser: boolean; + private _relationshipStatus: number; + + constructor(wrapper: IMessageDataWrapper) + { + if(!wrapper) throw new Error('invalid_wrapper'); + + this._id = wrapper.readInt(); + this._name = wrapper.readString(); + this._gender = wrapper.readInt(); + this._online = wrapper.readBoolean(); + this._followingAllowed = wrapper.readBoolean(); + this._figure = wrapper.readString(); + this._categoryId = wrapper.readInt(); + this._motto = wrapper.readString(); + this._realName = wrapper.readString(); + this._lastAccess = wrapper.readString(); + this._persistedMessageUser = wrapper.readBoolean(); + this._vipMember = wrapper.readBoolean(); + this._pocketHabboUser = wrapper.readBoolean(); + this._relationshipStatus = wrapper.readShort(); + } + + public get id(): number + { + return this._id; + } + + public get name(): string + { + return this._name; + } + + public get gender(): number + { + return this._gender; + } + + public get online(): boolean + { + return this._online; + } + + public get followingAllowed(): boolean + { + return this._followingAllowed; + } + + public get figure(): string + { + return this._figure; + } + + public get categoryId(): number + { + return this._categoryId; + } + + public get motto(): string + { + return this._motto; + } + + public get lastAccess(): string + { + return this._lastAccess; + } + + public get realName(): string + { + return this._realName; + } + + public get persistedMessageUser(): boolean + { + return this._persistedMessageUser; + } + + public get vipMember(): boolean + { + return this._vipMember; + } + + public get pocketHabboUser(): boolean + { + return this._pocketHabboUser; + } + + public get relationshipStatus(): number + { + return this._relationshipStatus; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/friendlist/FriendRequestData.ts b/src/nitro/communication/messages/incoming/friendlist/FriendRequestData.ts new file mode 100644 index 00000000..96d5a734 --- /dev/null +++ b/src/nitro/communication/messages/incoming/friendlist/FriendRequestData.ts @@ -0,0 +1,39 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; + +export class FriendRequestData +{ + private _requestId: number; + private _requesterName: string; + private _requesterUserId: number; + private _figureString: string; + + constructor(wrapper: IMessageDataWrapper) + { + if(!wrapper) throw new Error('invalid_wrapper'); + + this._requestId = wrapper.readInt(); + this._requesterName = wrapper.readString(); + this._figureString = wrapper.readString(); + this._requesterUserId = this._requestId; + } + + public get requestId(): number + { + return this._requestId; + } + + public get requesterName(): string + { + return this._requesterName; + } + + public get requesterUserId(): number + { + return this._requesterUserId; + } + + public get figureString(): string + { + return this._figureString; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/friendlist/FriendRequestsEvent.ts b/src/nitro/communication/messages/incoming/friendlist/FriendRequestsEvent.ts new file mode 100644 index 00000000..cdd1349a --- /dev/null +++ b/src/nitro/communication/messages/incoming/friendlist/FriendRequestsEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { FriendRequestsParser } from '../../parser/friendlist/FriendRequestsParser'; + +export class FriendRequestsEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FriendRequestsParser); + } + + public getParser(): FriendRequestsParser + { + return this.parser as FriendRequestsParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/friendlist/HabboSearchResultData.ts b/src/nitro/communication/messages/incoming/friendlist/HabboSearchResultData.ts new file mode 100644 index 00000000..11b8bc3f --- /dev/null +++ b/src/nitro/communication/messages/incoming/friendlist/HabboSearchResultData.ts @@ -0,0 +1,74 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; + +export class HabboSearchResultData +{ + private _avatarId: number; + private _avatarName: string; + private _avatarMotto: string; + private _isAvatarOnline: boolean; + private _canFollow: boolean; + private _avatarGender: number; + private _avatarFigure: string; + private _lastOnlineData: string; + private _realName: string; + + constructor(wrapper: IMessageDataWrapper) + { + if(!wrapper) throw new Error('invalid_wrapper'); + + this._avatarId = wrapper.readInt(); + this._avatarName = wrapper.readString(); + this._avatarMotto = wrapper.readString(); + this._isAvatarOnline = wrapper.readBoolean(); + this._canFollow = wrapper.readBoolean(); + this._avatarGender = wrapper.readInt(); + this._avatarFigure = wrapper.readString(); + this._lastOnlineData = wrapper.readString(); + this._realName = wrapper.readString(); + } + + public get avatarId(): number + { + return this._avatarId; + } + + public get avatarName(): string + { + return this._avatarName; + } + + public get avatarMotto(): string + { + return this._avatarMotto; + } + + public get isAvatarOnline(): boolean + { + return this._isAvatarOnline; + } + + public get canFollow(): boolean + { + return this._canFollow; + } + + public get avatarGender(): number + { + return this._avatarGender; + } + + public get avatarFigure(): string + { + return this._avatarFigure; + } + + public get lastOnlineData(): string + { + return this._lastOnlineData; + } + + public get realName(): string + { + return this._realName; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/friendlist/HabboSearchResultEvent.ts b/src/nitro/communication/messages/incoming/friendlist/HabboSearchResultEvent.ts new file mode 100644 index 00000000..41c1b840 --- /dev/null +++ b/src/nitro/communication/messages/incoming/friendlist/HabboSearchResultEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { HabboSearchResultParser } from '../../parser/friendlist/HabboSearchResultParser'; + +export class HabboSearchResultEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, HabboSearchResultParser); + } + + public getParser(): HabboSearchResultParser + { + return this.parser as HabboSearchResultParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/friendlist/InstantMessageErrorEvent.ts b/src/nitro/communication/messages/incoming/friendlist/InstantMessageErrorEvent.ts new file mode 100644 index 00000000..54991a69 --- /dev/null +++ b/src/nitro/communication/messages/incoming/friendlist/InstantMessageErrorEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { InstantMessageErrorParser } from '../../parser/friendlist/InstantMessageErrorParser'; + +export class InstantMessageErrorEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, InstantMessageErrorParser); + } + + public getParser(): InstantMessageErrorParser + { + return this.parser as InstantMessageErrorParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/friendlist/MessageErrorEvent.ts b/src/nitro/communication/messages/incoming/friendlist/MessageErrorEvent.ts new file mode 100644 index 00000000..2a2eb4db --- /dev/null +++ b/src/nitro/communication/messages/incoming/friendlist/MessageErrorEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { MessageErrorParser } from '../../parser/friendlist/MessageErrorParser'; + +export class MessageErrorEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, MessageErrorParser); + } + + public getParser(): MessageErrorParser + { + return this.parser as MessageErrorParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/friendlist/MessengerInitEvent.ts b/src/nitro/communication/messages/incoming/friendlist/MessengerInitEvent.ts new file mode 100644 index 00000000..3b03026b --- /dev/null +++ b/src/nitro/communication/messages/incoming/friendlist/MessengerInitEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { MessengerInitParser } from '../../parser/friendlist/MessengerInitParser'; + +export class MessengerInitEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, MessengerInitParser); + } + + public getParser(): MessengerInitParser + { + return this.parser as MessengerInitParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/friendlist/MiniMailNewMessageEvent.ts b/src/nitro/communication/messages/incoming/friendlist/MiniMailNewMessageEvent.ts new file mode 100644 index 00000000..64d40aa2 --- /dev/null +++ b/src/nitro/communication/messages/incoming/friendlist/MiniMailNewMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { MiniMailNewMessageParser } from '../../parser/friendlist/MiniMailNewMessageParser'; + +export class MiniMailNewMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, MiniMailNewMessageParser); + } + + public getParser(): MiniMailNewMessageParser + { + return this.parser as MiniMailNewMessageParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/friendlist/MiniMailUnreadCountEvent.ts b/src/nitro/communication/messages/incoming/friendlist/MiniMailUnreadCountEvent.ts new file mode 100644 index 00000000..36d1fcf6 --- /dev/null +++ b/src/nitro/communication/messages/incoming/friendlist/MiniMailUnreadCountEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { MiniMailUnreadCountParser } from '../../parser/friendlist/MiniMailUnreadCountParser'; + +export class MiniMailUnreadCountEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, MiniMailUnreadCountParser); + } + + public getParser(): MiniMailUnreadCountParser + { + return this.parser as MiniMailUnreadCountParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/friendlist/NewConsoleMessageEvent.ts b/src/nitro/communication/messages/incoming/friendlist/NewConsoleMessageEvent.ts new file mode 100644 index 00000000..5878bc65 --- /dev/null +++ b/src/nitro/communication/messages/incoming/friendlist/NewConsoleMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { NewConsoleMessageParser } from '../../parser/friendlist/NewConsoleMessageParser'; + +export class NewConsoleMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, NewConsoleMessageParser); + } + + public getParser(): NewConsoleMessageParser + { + return this.parser as NewConsoleMessageParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/friendlist/NewFriendRequestEvent.ts b/src/nitro/communication/messages/incoming/friendlist/NewFriendRequestEvent.ts new file mode 100644 index 00000000..9cb46a60 --- /dev/null +++ b/src/nitro/communication/messages/incoming/friendlist/NewFriendRequestEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { NewFriendRequestParser } from '../../parser/friendlist/NewFriendRequestMessageParser'; + +export class NewFriendRequestEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, NewFriendRequestParser); + } + + public getParser(): NewFriendRequestParser + { + return this.parser as NewFriendRequestParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/friendlist/RoomInviteErrorEvent.ts b/src/nitro/communication/messages/incoming/friendlist/RoomInviteErrorEvent.ts new file mode 100644 index 00000000..d3d9dde5 --- /dev/null +++ b/src/nitro/communication/messages/incoming/friendlist/RoomInviteErrorEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { RoomInviteErrorParser } from '../../parser/friendlist/RoomInviteErrorParser'; + +export class RoomInviteErrorEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomInviteErrorParser); + } + + public getParser(): RoomInviteErrorParser + { + return this.parser as RoomInviteErrorParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/friendlist/RoomInviteEvent.ts b/src/nitro/communication/messages/incoming/friendlist/RoomInviteEvent.ts new file mode 100644 index 00000000..859842fe --- /dev/null +++ b/src/nitro/communication/messages/incoming/friendlist/RoomInviteEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { RoomInviteParser } from '../../parser/friendlist/RoomInviteMessageParser'; + +export class RoomInviteEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomInviteParser); + } + + public getParser(): RoomInviteParser + { + return this.parser as RoomInviteParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/game/LoadGameUrlEvent.ts b/src/nitro/communication/messages/incoming/game/LoadGameUrlEvent.ts new file mode 100644 index 00000000..85226e21 --- /dev/null +++ b/src/nitro/communication/messages/incoming/game/LoadGameUrlEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { LoadGameUrlParser } from '../../parser/game/LoadGameUrlParser'; + +export class LoadGameUrlEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, LoadGameUrlParser); + } + + public getParser(): LoadGameUrlParser + { + return this.parser as LoadGameUrlParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/generic/GenericErrorEvent.ts b/src/nitro/communication/messages/incoming/generic/GenericErrorEvent.ts new file mode 100644 index 00000000..7e13fc1e --- /dev/null +++ b/src/nitro/communication/messages/incoming/generic/GenericErrorEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { GenericErrorParser } from '../../parser/generic/GenericErrorParser'; + +export class GenericErrorEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, GenericErrorParser); + } + + public getParser(): GenericErrorParser + { + return this.parser as GenericErrorParser; + } +} diff --git a/src/nitro/communication/messages/incoming/group/GroupBadgePartsEvent.ts b/src/nitro/communication/messages/incoming/group/GroupBadgePartsEvent.ts new file mode 100644 index 00000000..d9c6ca97 --- /dev/null +++ b/src/nitro/communication/messages/incoming/group/GroupBadgePartsEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { GroupBadgePartsParser } from '../../parser/group/GroupBadgePartsParser'; + +export class GroupBadgePartsEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, GroupBadgePartsParser); + } + + public getParser(): GroupBadgePartsParser + { + return this.parser as GroupBadgePartsParser; + } +} diff --git a/src/nitro/communication/messages/incoming/group/GroupBuyDataEvent.ts b/src/nitro/communication/messages/incoming/group/GroupBuyDataEvent.ts new file mode 100644 index 00000000..23a8e187 --- /dev/null +++ b/src/nitro/communication/messages/incoming/group/GroupBuyDataEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { GroupBuyDataParser } from '../../parser/group/GroupBuyDataParser'; + +export class GroupBuyDataEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, GroupBuyDataParser); + } + + public getParser(): GroupBuyDataParser + { + return this.parser as GroupBuyDataParser; + } +} diff --git a/src/nitro/communication/messages/incoming/group/GroupConfirmMemberRemoveEvent.ts b/src/nitro/communication/messages/incoming/group/GroupConfirmMemberRemoveEvent.ts new file mode 100644 index 00000000..3550173c --- /dev/null +++ b/src/nitro/communication/messages/incoming/group/GroupConfirmMemberRemoveEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { GroupConfirmMemberRemoveParser } from '../../parser/group/GroupConfirmMemberRemoveParser'; + +export class GroupConfirmMemberRemoveEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, GroupConfirmMemberRemoveParser); + } + + public getParser(): GroupConfirmMemberRemoveParser + { + return this.parser as GroupConfirmMemberRemoveParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/group/GroupInformationEvent.ts b/src/nitro/communication/messages/incoming/group/GroupInformationEvent.ts new file mode 100644 index 00000000..aa3d9afb --- /dev/null +++ b/src/nitro/communication/messages/incoming/group/GroupInformationEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { GroupInformationParser } from '../../parser/group/GroupInformationParser'; + +export class GroupInformationEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, GroupInformationParser); + } + + public getParser(): GroupInformationParser + { + return this.parser as GroupInformationParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/group/GroupMembersEvent.ts b/src/nitro/communication/messages/incoming/group/GroupMembersEvent.ts new file mode 100644 index 00000000..34e11f6a --- /dev/null +++ b/src/nitro/communication/messages/incoming/group/GroupMembersEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { GroupMembersParser } from '../../parser/group/GroupMembersParser'; + +export class GroupMembersEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, GroupMembersParser); + } + + public getParser(): GroupMembersParser + { + return this.parser as GroupMembersParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/group/GroupSettingsEvent.ts b/src/nitro/communication/messages/incoming/group/GroupSettingsEvent.ts new file mode 100644 index 00000000..6cb4c775 --- /dev/null +++ b/src/nitro/communication/messages/incoming/group/GroupSettingsEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { GroupSettingsParser } from '../../parser/group/GroupSettingsParser'; + +export class GroupSettingsEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, GroupSettingsParser); + } + + public getParser(): GroupSettingsParser + { + return this.parser as GroupSettingsParser; + } +} diff --git a/src/nitro/communication/messages/incoming/help/CallForHelpResultMessageEvent.ts b/src/nitro/communication/messages/incoming/help/CallForHelpResultMessageEvent.ts new file mode 100644 index 00000000..277a3166 --- /dev/null +++ b/src/nitro/communication/messages/incoming/help/CallForHelpResultMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { CallForHelpResultMessageParser } from '../../parser/help/CallForHelpResultMessageParser'; + +export class CallForHelpResultMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, CallForHelpResultMessageParser); + } + + public getParser(): CallForHelpResultMessageParser + { + return this.parser as CallForHelpResultMessageParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/inventory/achievements/Achievement.ts b/src/nitro/communication/messages/incoming/inventory/achievements/Achievement.ts new file mode 100644 index 00000000..fc7efce0 --- /dev/null +++ b/src/nitro/communication/messages/incoming/inventory/achievements/Achievement.ts @@ -0,0 +1,156 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; + +export class Achievement +{ + public static _Str_21736: number = -1; + public static _Str_21318: number = 0; + public static _Str_15908: number = 1; + public static _Str_20384: number = 2; + + private _achievementId: number; + private _level: number; + private _badgeId: string; + private _Str_6791: number; + private _Str_18274: number; + private _Str_10280: number; + private _Str_12282: number; + private _Str_19007: number; + private _Str_16081: boolean; + private _category: string; + private _Str_21707: string; + private _Str_20339: number; + private _Str_19099: number; + + private _unseen: number = 0; + + constructor(wrapper: IMessageDataWrapper) + { + if(!wrapper) throw new Error('invalid_parser'); + + this._achievementId = wrapper.readInt(); + this._level = wrapper.readInt(); + this._badgeId = wrapper.readString(); + this._Str_6791 = wrapper.readInt(); + this._Str_18274 = Math.max(1, wrapper.readInt()); + this._Str_10280 = wrapper.readInt(); + this._Str_12282 = wrapper.readInt(); + this._Str_19007 = wrapper.readInt(); + this._Str_16081 = wrapper.readBoolean(); + this._category = wrapper.readString(); + this._Str_21707 = wrapper.readString(); + this._Str_20339 = wrapper.readInt(); + this._Str_19099 = wrapper.readInt(); + } + + public get achievementId(): number + { + return this._achievementId; + } + + public get badgeId(): string + { + return this._badgeId; + } + + public get level(): number + { + return this._level; + } + + public get _Str_25209(): number + { + return this._Str_6791; + } + + public get _Str_24142(): number + { + return (this._Str_18274 - this._Str_6791); + } + + public get rewardAmount(): number + { + return this._Str_10280; + } + + public get rewardType(): number + { + return this._Str_12282; + } + + public get _Str_22939(): number + { + return (this._Str_19007 - this._Str_6791); + } + + public get _Str_7518(): boolean + { + return this._Str_16081; + } + + public get category(): string + { + return this._category; + } + + public get _Str_25896(): string + { + return this._Str_21707; + } + + public get totalLevels(): number + { + return this._Str_20339; + } + + public get _Str_10438(): boolean + { + return (this._level > 1) || (this._Str_16081); + } + + public _Str_24410(): void + { + this._Str_19007 = this._Str_18274; + } + + public get _Str_24874(): number + { + return this._Str_19099; + } + + public get progress(): number + { + return this._Str_19007; + } + + public get toNextProgress(): number + { + return this._Str_18274; + } + + public set unseen(unseen: number) + { + this._unseen = unseen; + } + + public get unseen(): number + { + return this._unseen; + } + + public reset(badge: Achievement) + { + this._achievementId = badge._achievementId; + this._level = badge._level; + this._badgeId = badge._badgeId; + this._Str_6791 = badge._Str_6791; + this._Str_18274 = badge._Str_18274; + this._Str_10280 = badge._Str_10280; + this._Str_12282 = badge._Str_12282; + this._Str_19007 = badge._Str_19007; + this._Str_16081 = badge._Str_16081; + this._category = badge.category; + this._Str_21707 = badge._Str_21707; + this._Str_20339 = badge._Str_20339; + this._Str_19099 = badge._Str_19099; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/inventory/achievements/AchievementEvent.ts b/src/nitro/communication/messages/incoming/inventory/achievements/AchievementEvent.ts new file mode 100644 index 00000000..3d6a1bf5 --- /dev/null +++ b/src/nitro/communication/messages/incoming/inventory/achievements/AchievementEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { AchievementParser } from '../../../parser/inventory/achievements/AchievementParser'; + +export class AchievementEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, AchievementParser); + } + + public getParser(): AchievementParser + { + return this.parser as AchievementParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/inventory/achievements/AchievementResolution.ts b/src/nitro/communication/messages/incoming/inventory/achievements/AchievementResolution.ts new file mode 100644 index 00000000..39f2577c --- /dev/null +++ b/src/nitro/communication/messages/incoming/inventory/achievements/AchievementResolution.ts @@ -0,0 +1,59 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; + +export class AchievementResolution +{ + public static _Str_16945: number = 0; + + private _achievementId: number; + private _level: number; + private _badgeId: string; + private _Str_8741: number; + private _state: number; + + constructor(wrapper: IMessageDataWrapper) + { + this._achievementId = wrapper.readInt(); + this._level = wrapper.readInt(); + this._badgeId = wrapper.readString(); + this._Str_8741 = wrapper.readInt(); + this._state = wrapper.readInt(); + } + + public dispose(): void + { + this._achievementId = 0; + this._level = 0; + this._badgeId = ''; + this._Str_8741 = 0; + } + + public get achievementId(): number + { + return this._achievementId; + } + + public get level(): number + { + return this._level; + } + + public get badgeId(): string + { + return this._badgeId; + } + + public get _Str_20240(): number + { + return this._Str_8741; + } + + public get enabled(): boolean + { + return (this._state === AchievementResolution._Str_16945); + } + + public get state(): number + { + return this._state; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/inventory/achievements/AchievementsEvent.ts b/src/nitro/communication/messages/incoming/inventory/achievements/AchievementsEvent.ts new file mode 100644 index 00000000..f5698094 --- /dev/null +++ b/src/nitro/communication/messages/incoming/inventory/achievements/AchievementsEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { AchievementsParser } from '../../../parser/inventory/achievements/AchievementsParser'; + +export class AchievementsEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, AchievementsParser); + } + + public getParser(): AchievementsParser + { + return this.parser as AchievementsParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/inventory/achievements/AchievementsScoreEvent.ts b/src/nitro/communication/messages/incoming/inventory/achievements/AchievementsScoreEvent.ts new file mode 100644 index 00000000..92735e26 --- /dev/null +++ b/src/nitro/communication/messages/incoming/inventory/achievements/AchievementsScoreEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { AchievementsScoreParser } from '../../../parser/inventory/achievements/AchievementsScoreParser'; + +export class AchievementsScoreEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, AchievementsScoreParser); + } + + public getParser(): AchievementsScoreParser + { + return this.parser as AchievementsScoreParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/inventory/avatareffect/AvatarEffect.ts b/src/nitro/communication/messages/incoming/inventory/avatareffect/AvatarEffect.ts new file mode 100644 index 00000000..01c08256 --- /dev/null +++ b/src/nitro/communication/messages/incoming/inventory/avatareffect/AvatarEffect.ts @@ -0,0 +1,69 @@ +export class AvatarEffect +{ + private _type: number; + private _subType: number; + private _duration: number; + private _inactiveEffectsInInventory: number; + private _secondsLeftIfActive: number; + private _permanent: boolean; + + public get type(): number + { + return this._type; + } + + public set type(k: number) + { + this._type = k; + } + + public get _Str_3882(): number + { + return this._subType; + } + + public set _Str_3882(k: number) + { + this._subType = k; + } + + public get duration(): number + { + return this._duration; + } + + public set duration(k: number) + { + this._duration = k; + } + + public get _Str_18572(): number + { + return this._inactiveEffectsInInventory; + } + + public set _Str_18572(k: number) + { + this._inactiveEffectsInInventory = k; + } + + public get _Str_12185(): number + { + return this._secondsLeftIfActive; + } + + public set _Str_12185(k: number) + { + this._secondsLeftIfActive = k; + } + + public get _Str_4010(): boolean + { + return this._permanent; + } + + public set _Str_4010(k: boolean) + { + this._permanent = k; + } +} diff --git a/src/nitro/communication/messages/incoming/inventory/avatareffect/AvatarEffectActivatedEvent.ts b/src/nitro/communication/messages/incoming/inventory/avatareffect/AvatarEffectActivatedEvent.ts new file mode 100644 index 00000000..47ff020b --- /dev/null +++ b/src/nitro/communication/messages/incoming/inventory/avatareffect/AvatarEffectActivatedEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { AvatarEffectActivatedParser } from '../../../parser/inventory/avatareffect/AvatarEffectActivatedParser'; + +export class AvatarEffectActivatedEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, AvatarEffectActivatedParser); + } + + public getParser(): AvatarEffectActivatedParser + { + return this.parser as AvatarEffectActivatedParser; + } +} diff --git a/src/nitro/communication/messages/incoming/inventory/avatareffect/AvatarEffectAddedEvent.ts b/src/nitro/communication/messages/incoming/inventory/avatareffect/AvatarEffectAddedEvent.ts new file mode 100644 index 00000000..78d17fa0 --- /dev/null +++ b/src/nitro/communication/messages/incoming/inventory/avatareffect/AvatarEffectAddedEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { AvatarEffectAddedParser } from '../../../parser/inventory/avatareffect/AvatarEffectAddedParser'; + +export class AvatarEffectAddedEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, AvatarEffectAddedParser); + } + + public getParser(): AvatarEffectAddedParser + { + return this.parser as AvatarEffectAddedParser; + } +} diff --git a/src/nitro/communication/messages/incoming/inventory/avatareffect/AvatarEffectExpiredEvent.ts b/src/nitro/communication/messages/incoming/inventory/avatareffect/AvatarEffectExpiredEvent.ts new file mode 100644 index 00000000..e2f6cd25 --- /dev/null +++ b/src/nitro/communication/messages/incoming/inventory/avatareffect/AvatarEffectExpiredEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { AvatarEffectExpiredParser } from '../../../parser/inventory/avatareffect/AvatarEffectExpiredParser'; + +export class AvatarEffectExpiredEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, AvatarEffectExpiredParser); + } + + public getParser(): AvatarEffectExpiredParser + { + return this.parser as AvatarEffectExpiredParser; + } +} diff --git a/src/nitro/communication/messages/incoming/inventory/avatareffect/AvatarEffectSelectedEvent.ts b/src/nitro/communication/messages/incoming/inventory/avatareffect/AvatarEffectSelectedEvent.ts new file mode 100644 index 00000000..88b7bbc0 --- /dev/null +++ b/src/nitro/communication/messages/incoming/inventory/avatareffect/AvatarEffectSelectedEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { AvatarEffectSelectedParser } from '../../../parser/inventory/avatareffect/AvatarEffectSelectedParser'; + +export class AvatarEffectSelectedEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, AvatarEffectSelectedParser); + } + + public getParser(): AvatarEffectSelectedParser + { + return this.parser as AvatarEffectSelectedParser; + } +} diff --git a/src/nitro/communication/messages/incoming/inventory/avatareffect/AvatarEffectsEvent.ts b/src/nitro/communication/messages/incoming/inventory/avatareffect/AvatarEffectsEvent.ts new file mode 100644 index 00000000..2041f9d1 --- /dev/null +++ b/src/nitro/communication/messages/incoming/inventory/avatareffect/AvatarEffectsEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { AvatarEffectsParser } from '../../../parser/inventory/avatareffect/AvatarEffectsParser'; + +export class AvatarEffectsEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, AvatarEffectsParser); + } + + public getParser(): AvatarEffectsParser + { + return this.parser as AvatarEffectsParser; + } +} diff --git a/src/nitro/communication/messages/incoming/inventory/badges/BadgesEvent.ts b/src/nitro/communication/messages/incoming/inventory/badges/BadgesEvent.ts new file mode 100644 index 00000000..bae0c33d --- /dev/null +++ b/src/nitro/communication/messages/incoming/inventory/badges/BadgesEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { BadgesParser } from '../../../parser/inventory/badges/BadgesParser'; + +export class BadgesEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, BadgesParser); + } + + public getParser(): BadgesParser + { + return this.parser as BadgesParser; + } +} diff --git a/src/nitro/communication/messages/incoming/inventory/badges/_Str_8120.ts b/src/nitro/communication/messages/incoming/inventory/badges/_Str_8120.ts new file mode 100644 index 00000000..f3413334 --- /dev/null +++ b/src/nitro/communication/messages/incoming/inventory/badges/_Str_8120.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { _Str_7491 } from '../../../parser/inventory/badges/_Str_7491'; + +export class _Str_8120 extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, _Str_7491); + } + + public getParser(): _Str_7491 + { + return this.parser as _Str_7491; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/inventory/badges/_Str_8179.ts b/src/nitro/communication/messages/incoming/inventory/badges/_Str_8179.ts new file mode 100644 index 00000000..15feb804 --- /dev/null +++ b/src/nitro/communication/messages/incoming/inventory/badges/_Str_8179.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { _Str_9135 } from '../../../parser/inventory/badges/_Str_9135'; + +export class _Str_8179 extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, _Str_9135); + } + + public getParser(): _Str_9135 + { + return this.parser as _Str_9135; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/inventory/badges/_Str_8980.ts b/src/nitro/communication/messages/incoming/inventory/badges/_Str_8980.ts new file mode 100644 index 00000000..75597335 --- /dev/null +++ b/src/nitro/communication/messages/incoming/inventory/badges/_Str_8980.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { _Str_7305 } from '../../../parser/inventory/badges/_Str_7305'; + +export class _Str_8980 extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, _Str_7305); + } + + public getParser(): _Str_7305 + { + return this.parser as _Str_7305; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/inventory/bots/BotAddedToInventoryEvent.ts b/src/nitro/communication/messages/incoming/inventory/bots/BotAddedToInventoryEvent.ts new file mode 100644 index 00000000..fe55b447 --- /dev/null +++ b/src/nitro/communication/messages/incoming/inventory/bots/BotAddedToInventoryEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { BotAddedToInventoryParser } from '../../../parser/inventory/bots/BotAddedToInventoryParser'; + +export class BotAddedToInventoryEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, BotAddedToInventoryParser); + } + + public getParser(): BotAddedToInventoryParser + { + return this.parser as BotAddedToInventoryParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/inventory/bots/BotInventoryEvent.ts b/src/nitro/communication/messages/incoming/inventory/bots/BotInventoryEvent.ts new file mode 100644 index 00000000..e5452974 --- /dev/null +++ b/src/nitro/communication/messages/incoming/inventory/bots/BotInventoryEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { BotInventoryParser } from '../../../parser/inventory/bots/BotReceivedMessageParser'; + +export class BotInventoryEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, BotInventoryParser); + } + + public getParser(): BotInventoryParser + { + return this.parser as BotInventoryParser; + } +} diff --git a/src/nitro/communication/messages/incoming/inventory/bots/BotInventoryMessageEvent.ts b/src/nitro/communication/messages/incoming/inventory/bots/BotInventoryMessageEvent.ts new file mode 100644 index 00000000..421e35a7 --- /dev/null +++ b/src/nitro/communication/messages/incoming/inventory/bots/BotInventoryMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { BotInventoryMessageParser } from '../../../parser/inventory/bots/BotInventoryMessageParser'; + +export class BotInventoryMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, BotInventoryMessageParser); + } + + public getParser(): BotInventoryMessageParser + { + return this.parser as BotInventoryMessageParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/inventory/bots/BotRemovedFromInventoryEvent.ts b/src/nitro/communication/messages/incoming/inventory/bots/BotRemovedFromInventoryEvent.ts new file mode 100644 index 00000000..e2400316 --- /dev/null +++ b/src/nitro/communication/messages/incoming/inventory/bots/BotRemovedFromInventoryEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { BotRemovedFromInventoryParser } from '../../../parser/inventory/bots/BotRemovedFromInventoryParser'; + +export class BotRemovedFromInventoryEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, BotRemovedFromInventoryParser); + } + + public getParser(): BotRemovedFromInventoryParser + { + return this.parser as BotRemovedFromInventoryParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/inventory/clothes/FigureSetIdsMessageEvent.ts b/src/nitro/communication/messages/incoming/inventory/clothes/FigureSetIdsMessageEvent.ts new file mode 100644 index 00000000..1b68df23 --- /dev/null +++ b/src/nitro/communication/messages/incoming/inventory/clothes/FigureSetIdsMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { FigureSetIdsMessageParser } from '../../../parser/inventory/clothing/FigureSetIdsMessageParser'; + +export class FigureSetIdsMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FigureSetIdsMessageParser); + } + + public getParser(): FigureSetIdsMessageParser + { + return this.parser as FigureSetIdsMessageParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/inventory/clothes/_Str_16135.ts b/src/nitro/communication/messages/incoming/inventory/clothes/_Str_16135.ts new file mode 100644 index 00000000..073b3397 --- /dev/null +++ b/src/nitro/communication/messages/incoming/inventory/clothes/_Str_16135.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { _Str_8728 } from '../../../parser/inventory/clothing/_Str_8728'; + +export class _Str_16135 extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, _Str_8728); + } + + public getParser(): _Str_8728 + { + return this.parser as _Str_8728; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/inventory/clothes/_Str_17532.ts b/src/nitro/communication/messages/incoming/inventory/clothes/_Str_17532.ts new file mode 100644 index 00000000..ecfb0e5f --- /dev/null +++ b/src/nitro/communication/messages/incoming/inventory/clothes/_Str_17532.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { _Str_9021 } from '../../../parser/inventory/clothing/_Str_9021'; + +export class _Str_17532 extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, _Str_9021); + } + + public getParser(): _Str_9021 + { + return this.parser as _Str_9021; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/inventory/furni/FurnitureListAddOrUpdateEvent.ts b/src/nitro/communication/messages/incoming/inventory/furni/FurnitureListAddOrUpdateEvent.ts new file mode 100644 index 00000000..91ccaffe --- /dev/null +++ b/src/nitro/communication/messages/incoming/inventory/furni/FurnitureListAddOrUpdateEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { FurnitureListAddOrUpdateParser } from '../../../parser/inventory/furniture/FurnitureListAddOrUpdateParser'; + +export class FurnitureListAddOrUpdateEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FurnitureListAddOrUpdateParser); + } + + public getParser(): FurnitureListAddOrUpdateParser + { + return this.parser as FurnitureListAddOrUpdateParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/inventory/furni/FurnitureListEvent.ts b/src/nitro/communication/messages/incoming/inventory/furni/FurnitureListEvent.ts new file mode 100644 index 00000000..b0a9384c --- /dev/null +++ b/src/nitro/communication/messages/incoming/inventory/furni/FurnitureListEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { FurnitureListParser } from '../../../parser/inventory/furniture/FurnitureListParser'; + +export class FurnitureListEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FurnitureListParser); + } + + public getParser(): FurnitureListParser + { + return this.parser as FurnitureListParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/inventory/furni/FurnitureListInvalidateEvent.ts b/src/nitro/communication/messages/incoming/inventory/furni/FurnitureListInvalidateEvent.ts new file mode 100644 index 00000000..b66972d6 --- /dev/null +++ b/src/nitro/communication/messages/incoming/inventory/furni/FurnitureListInvalidateEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { FurnitureListInvalidateParser } from '../../../parser/inventory/furniture/FurnitureListInvalidateParser'; + +export class FurnitureListInvalidateEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FurnitureListInvalidateParser); + } + + public getParser(): FurnitureListInvalidateParser + { + return this.parser as FurnitureListInvalidateParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/inventory/furni/FurnitureListRemovedEvent.ts b/src/nitro/communication/messages/incoming/inventory/furni/FurnitureListRemovedEvent.ts new file mode 100644 index 00000000..185706f1 --- /dev/null +++ b/src/nitro/communication/messages/incoming/inventory/furni/FurnitureListRemovedEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { FurnitureListRemovedParser } from '../../../parser/inventory/furniture/FurnitureListRemovedParser'; + +export class FurnitureListRemovedEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FurnitureListRemovedParser); + } + + public getParser(): FurnitureListRemovedParser + { + return this.parser as FurnitureListRemovedParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/inventory/furni/FurniturePostItPlacedEvent.ts b/src/nitro/communication/messages/incoming/inventory/furni/FurniturePostItPlacedEvent.ts new file mode 100644 index 00000000..af96c5f3 --- /dev/null +++ b/src/nitro/communication/messages/incoming/inventory/furni/FurniturePostItPlacedEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { FurniturePostItPlacedParser } from '../../../parser/inventory/furniture/FurniturePostItPlacedParser'; + +export class FurniturePostItPlacedEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FurniturePostItPlacedParser); + } + + public getParser(): FurniturePostItPlacedParser + { + return this.parser as FurniturePostItPlacedParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/inventory/furni/IFurnitureItemData.ts b/src/nitro/communication/messages/incoming/inventory/furni/IFurnitureItemData.ts new file mode 100644 index 00000000..813d08b2 --- /dev/null +++ b/src/nitro/communication/messages/incoming/inventory/furni/IFurnitureItemData.ts @@ -0,0 +1,28 @@ +import { IObjectData } from '../../../../../room/object/data/IObjectData'; + +export interface IFurnitureItemData +{ + itemId: number; + furniType: string; + ref: number; + spriteId: number; + category: number; + stuffData: IObjectData; + isGroupable: boolean; + isRecycleable: boolean; + tradable: boolean; + sellable: boolean; + secondsToExpiration: number; + flatId: number; + slotId: string; + _Str_3951: number; + _Str_2794: number; + rentable: boolean; + isWallItem: boolean; + hasRentPeriodStarted: boolean; + _Str_10616: number; + _Str_8932: number; + _Str_9050: number; + _Str_9408: number; + _Str_19297: boolean; +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/inventory/furni/gifts/FurnitureGiftOpenedEvent.ts b/src/nitro/communication/messages/incoming/inventory/furni/gifts/FurnitureGiftOpenedEvent.ts new file mode 100644 index 00000000..b95a8467 --- /dev/null +++ b/src/nitro/communication/messages/incoming/inventory/furni/gifts/FurnitureGiftOpenedEvent.ts @@ -0,0 +1,17 @@ +import { IMessageEvent } from '../../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../../core/communication/messages/MessageEvent'; +import { FurnitureGiftOpenedParser } from '../../../../parser/inventory/furniture/FurnitureGiftOpenedParser'; + +// see _Str_9591 +export class FurnitureGiftOpenedEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FurnitureGiftOpenedParser); + } + + public getParser(): FurnitureGiftOpenedParser + { + return this.parser as FurnitureGiftOpenedParser; + } +} diff --git a/src/nitro/communication/messages/incoming/inventory/pets/PetAddedToInventoryEvent.ts b/src/nitro/communication/messages/incoming/inventory/pets/PetAddedToInventoryEvent.ts new file mode 100644 index 00000000..31eb0db6 --- /dev/null +++ b/src/nitro/communication/messages/incoming/inventory/pets/PetAddedToInventoryEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { PetAddedToInventoryParser } from '../../../parser/inventory/pets/PetAddedToInventoryParser'; + +export class PetAddedToInventoryEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, PetAddedToInventoryParser); + } + + public getParser(): PetAddedToInventoryParser + { + return this.parser as PetAddedToInventoryParser; + } +} diff --git a/src/nitro/communication/messages/incoming/inventory/pets/PetInventoryEvent.ts b/src/nitro/communication/messages/incoming/inventory/pets/PetInventoryEvent.ts new file mode 100644 index 00000000..cbf1cc23 --- /dev/null +++ b/src/nitro/communication/messages/incoming/inventory/pets/PetInventoryEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { PetInventoryParser } from '../../../parser/inventory/pets/PetInventoryParser'; + +export class PetInventoryEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, PetInventoryParser); + } + + public getParser(): PetInventoryParser + { + return this.parser as PetInventoryParser; + } +} diff --git a/src/nitro/communication/messages/incoming/inventory/pets/PetRemovedFromInventoryEvent.ts b/src/nitro/communication/messages/incoming/inventory/pets/PetRemovedFromInventoryEvent.ts new file mode 100644 index 00000000..0e7c833c --- /dev/null +++ b/src/nitro/communication/messages/incoming/inventory/pets/PetRemovedFromInventoryEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { PetRemovedFromInventoryParser } from '../../../parser/inventory/pets/PetRemovedFromInventoryParser'; + +export class PetRemovedFromInventory extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, PetRemovedFromInventoryParser); + } + + public getParser(): PetRemovedFromInventoryParser + { + return this.parser as PetRemovedFromInventoryParser; + } +} diff --git a/src/nitro/communication/messages/incoming/inventory/trading/TradingAcceptEvent.ts b/src/nitro/communication/messages/incoming/inventory/trading/TradingAcceptEvent.ts new file mode 100644 index 00000000..bc9e636a --- /dev/null +++ b/src/nitro/communication/messages/incoming/inventory/trading/TradingAcceptEvent.ts @@ -0,0 +1,26 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { TradingAcceptParser } from '../../../parser/inventory/trading/TradingAcceptParser'; + +export class TradingAcceptEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, TradingAcceptParser); + } + + public get _Str_4963(): number + { + return this.getParser()._Str_4963; + } + + public get _Str_15794(): boolean + { + return this.getParser()._Str_15794; + } + + public getParser(): TradingAcceptParser + { + return this.parser as TradingAcceptParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/inventory/trading/TradingCloseEvent.ts b/src/nitro/communication/messages/incoming/inventory/trading/TradingCloseEvent.ts new file mode 100644 index 00000000..e0957081 --- /dev/null +++ b/src/nitro/communication/messages/incoming/inventory/trading/TradingCloseEvent.ts @@ -0,0 +1,21 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { TradingCloseParser } from '../../../parser/inventory/trading/TradingCloseParser'; + +export class TradingCloseEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, TradingCloseParser); + } + + public get _Str_4963(): number + { + return this.getParser()._Str_4963; + } + + public getParser(): TradingCloseParser + { + return this.parser as TradingCloseParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/inventory/trading/TradingCompletedEvent.ts b/src/nitro/communication/messages/incoming/inventory/trading/TradingCompletedEvent.ts new file mode 100644 index 00000000..b1a1b462 --- /dev/null +++ b/src/nitro/communication/messages/incoming/inventory/trading/TradingCompletedEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { TradingCompletedParser } from '../../../parser/inventory/trading/TradingCompletedParser'; + +export class TradingCompletedEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, TradingCompletedParser); + } + + public getParser(): TradingCompletedParser + { + return this.parser as TradingCompletedParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/inventory/trading/TradingConfirmationEvent.ts b/src/nitro/communication/messages/incoming/inventory/trading/TradingConfirmationEvent.ts new file mode 100644 index 00000000..08b81fcf --- /dev/null +++ b/src/nitro/communication/messages/incoming/inventory/trading/TradingConfirmationEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { TradingConfirmationParser } from '../../../parser/inventory/trading/TradingConfirmationParser'; + +export class TradingConfirmationEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, TradingConfirmationParser); + } + + public getParser(): TradingConfirmationParser + { + return this.parser as TradingConfirmationParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/inventory/trading/TradingListItem.ts b/src/nitro/communication/messages/incoming/inventory/trading/TradingListItem.ts new file mode 100644 index 00000000..15b08418 --- /dev/null +++ b/src/nitro/communication/messages/incoming/inventory/trading/TradingListItem.ts @@ -0,0 +1,163 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { Nitro } from '../../../../../Nitro'; +import { IObjectData } from '../../../../../room/object/data/IObjectData'; +import { FurnitureDataParser } from '../../../parser/room/furniture/FurnitureDataParser'; +import { IFurnitureItemData } from '../furni/IFurnitureItemData'; + +export class TradingListItem implements IFurnitureItemData +{ + private _Str_5390: number; + private _isWallItem: boolean; + private _itemId: number; + private _furniType: string; + private _ref: number; + private _spriteId: number; + private _category: number; + private _stuffData: IObjectData; + private _Str_3182: number; + private _secondsToExpiration: number; + private _Str_9291: number; + private _Str_8744: number; + private _Str_9700: number; + private _isGroupable: boolean; + private _Str_2808: number; + private _flatId: number; + private _rentable: boolean; + private _hasRentPeriodStarted: boolean; + + constructor(wrapper: IMessageDataWrapper) + { + this._itemId = wrapper.readInt(); + this._furniType = wrapper.readString().toUpperCase(); + this._ref = wrapper.readInt(); + this._spriteId = wrapper.readInt(); + this._category = wrapper.readInt(); + this._isGroupable = wrapper.readBoolean(); + this._stuffData = FurnitureDataParser.parseObjectData(wrapper); + this._secondsToExpiration = -1; + this._Str_5390 = Nitro.instance.time; + this._hasRentPeriodStarted = false; + this._Str_9291 = wrapper.readInt(); + this._Str_8744 = wrapper.readInt(); + this._Str_9700 = wrapper.readInt(); + this._Str_3182 = ((this.furniType === 'S') ? wrapper.readInt() : -1); + this._flatId = -1; + this._rentable = false; + this._isWallItem = (this._furniType === 'I'); + } + + public get itemId(): number + { + return this._itemId; + } + + public get furniType(): string + { + return this._furniType; + } + + public get ref(): number + { + return this._ref; + } + + public get spriteId(): number + { + return this._spriteId; + } + + public get category(): number + { + return this._category; + } + + public get stuffData(): IObjectData + { + return this._stuffData; + } + + public get _Str_2794(): number + { + return this._Str_3182; + } + + public get secondsToExpiration(): number + { + return this._secondsToExpiration; + } + + public get _Str_8932(): number + { + return this._Str_9291; + } + + public get _Str_9050(): number + { + return this._Str_8744; + } + + public get _Str_9408(): number + { + return this._Str_9700; + } + + public get isGroupable(): boolean + { + return this._isGroupable; + } + + public get _Str_3951(): number + { + return this._Str_3182; + } + + public get flatId(): number + { + return this._flatId; + } + + public get rentable(): boolean + { + return this._rentable; + } + + public get isWallItem(): boolean + { + return this._isWallItem; + } + + public get hasRentPeriodStarted(): boolean + { + return this._hasRentPeriodStarted; + } + + public get _Str_10616(): number + { + return this._Str_5390; + } + + public get isRecycleable(): boolean + { + return true; + } + + public get tradable(): boolean + { + return true; + } + + public get sellable(): boolean + { + return true; + } + + public get slotId(): string + { + return null; + } + + public get _Str_19297(): boolean + { + return (this._furniType.indexOf('external_image') !== -1); + } +} diff --git a/src/nitro/communication/messages/incoming/inventory/trading/TradingListItemEvent.ts b/src/nitro/communication/messages/incoming/inventory/trading/TradingListItemEvent.ts new file mode 100644 index 00000000..8d91fd827 --- /dev/null +++ b/src/nitro/communication/messages/incoming/inventory/trading/TradingListItemEvent.ts @@ -0,0 +1,57 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { TradingListItemParser } from '../../../parser/inventory/trading/TradingListItemParser'; +import { TradingListItem } from './TradingListItem'; + +export class TradingListItemEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, TradingListItemParser); + } + + public get _Str_15162(): number + { + return this.getParser()._Str_15162; + } + + public get _Str_18215(): number + { + return this.getParser()._Str_18215; + } + + public get _Str_14946(): number + { + return this.getParser()._Str_14946; + } + + public get _Str_13801(): number + { + return this.getParser()._Str_13801; + } + + public get _Str_15709(): number + { + return this.getParser()._Str_15709; + } + + public get _Str_9138(): number + { + return this.getParser()._Str_9138; + } + + public get _Str_17841(): TradingListItem[] + { + return this.getParser()._Str_17841; + } + + public get _Str_17465(): TradingListItem[] + { + return this.getParser()._Str_17465; + } + + public getParser(): TradingListItemParser + { + return this.parser as TradingListItemParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/inventory/trading/TradingNotOpenEvent.ts b/src/nitro/communication/messages/incoming/inventory/trading/TradingNotOpenEvent.ts new file mode 100644 index 00000000..cb76ddfd --- /dev/null +++ b/src/nitro/communication/messages/incoming/inventory/trading/TradingNotOpenEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { TradingNotOpenParser } from '../../../parser/inventory/trading/TradingNotOpenParser'; + +export class TradingNotOpenEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, TradingNotOpenParser); + } + + public getParser(): TradingNotOpenParser + { + return this.parser as TradingNotOpenParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/inventory/trading/TradingOpenEvent.ts b/src/nitro/communication/messages/incoming/inventory/trading/TradingOpenEvent.ts new file mode 100644 index 00000000..2ed9243c --- /dev/null +++ b/src/nitro/communication/messages/incoming/inventory/trading/TradingOpenEvent.ts @@ -0,0 +1,36 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { TradingOpenParser } from '../../../parser/inventory/trading/TradingOpenParser'; + +export class TradingOpenEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, TradingOpenParser); + } + + public get _Str_4963(): number + { + return this.getParser()._Str_4963; + } + + public get _Str_16764(): boolean + { + return this.getParser()._Str_16764; + } + + public get _Str_17613(): number + { + return this.getParser()._Str_17613; + } + + public get _Str_13374(): boolean + { + return this.getParser()._Str_13374; + } + + public getParser(): TradingOpenParser + { + return this.parser as TradingOpenParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/inventory/trading/TradingOpenFailedEvent.ts b/src/nitro/communication/messages/incoming/inventory/trading/TradingOpenFailedEvent.ts new file mode 100644 index 00000000..0bbafe5c --- /dev/null +++ b/src/nitro/communication/messages/incoming/inventory/trading/TradingOpenFailedEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { TradingOpenFailedParser } from '../../../parser/inventory/trading/TradingOpenFailedParser'; + +export class TradingOpenFailedEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, TradingOpenFailedParser); + } + + public getParser(): TradingOpenFailedParser + { + return this.parser as TradingOpenFailedParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/inventory/trading/TradingOtherNotAllowedEvent.ts b/src/nitro/communication/messages/incoming/inventory/trading/TradingOtherNotAllowedEvent.ts new file mode 100644 index 00000000..3b0eb484 --- /dev/null +++ b/src/nitro/communication/messages/incoming/inventory/trading/TradingOtherNotAllowedEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { TradingOtherNotAllowedParser } from '../../../parser/inventory/trading/TradingOtherNotAllowedParser'; + +export class TradingOtherNotAllowedEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, TradingOtherNotAllowedParser); + } + + public getParser(): TradingOtherNotAllowedParser + { + return this.parser as TradingOtherNotAllowedParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/inventory/trading/TradingYouAreNotAllowedEvent.ts b/src/nitro/communication/messages/incoming/inventory/trading/TradingYouAreNotAllowedEvent.ts new file mode 100644 index 00000000..c77563a0 --- /dev/null +++ b/src/nitro/communication/messages/incoming/inventory/trading/TradingYouAreNotAllowedEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { TradingYouAreNotAllowedParser } from '../../../parser/inventory/trading/TradingYouAreNotAllowedParser'; + +export class TradingYouAreNotAllowedEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, TradingYouAreNotAllowedParser); + } + + public getParser(): TradingYouAreNotAllowedParser + { + return this.parser as TradingYouAreNotAllowedParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/moderation/ModeratorMessageEvent.ts b/src/nitro/communication/messages/incoming/moderation/ModeratorMessageEvent.ts new file mode 100644 index 00000000..d63d55ac --- /dev/null +++ b/src/nitro/communication/messages/incoming/moderation/ModeratorMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { ModeratorMessageParser } from '../../parser/moderation/ModeratorMessageParser'; + +export class ModeratorMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, ModeratorMessageParser); + } + + public getParser(): ModeratorMessageParser + { + return this.parser as ModeratorMessageParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/modtool/ModtoolCallForHelpTopicsEvent.ts b/src/nitro/communication/messages/incoming/modtool/ModtoolCallForHelpTopicsEvent.ts new file mode 100644 index 00000000..76d9094b --- /dev/null +++ b/src/nitro/communication/messages/incoming/modtool/ModtoolCallForHelpTopicsEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { ModtoolCFHTopicsParser } from '../../parser/modtool/ModtoolCFHTopicsParser'; + +export class ModtoolCallForHelpTopicsEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, ModtoolCFHTopicsParser); + } + + public getParser(): ModtoolCFHTopicsParser + { + return this.parser as ModtoolCFHTopicsParser; + } +} diff --git a/src/nitro/communication/messages/incoming/modtool/ModtoolMainEvent.ts b/src/nitro/communication/messages/incoming/modtool/ModtoolMainEvent.ts new file mode 100644 index 00000000..63814725 --- /dev/null +++ b/src/nitro/communication/messages/incoming/modtool/ModtoolMainEvent.ts @@ -0,0 +1,17 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { ModtoolRoomChatlogParser } from '../../parser/modtool/ModtoolRoomChatlogParser'; +import { ModtoolMainParser } from '../../parser/modtool/ModtoolMainParser'; + +export class ModtoolMainEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, ModtoolMainParser); + } + + public getParser(): ModtoolMainParser + { + return this.parser as ModtoolMainParser; + } +} diff --git a/src/nitro/communication/messages/incoming/modtool/ModtoolReceivedRoomsUserEvent.ts b/src/nitro/communication/messages/incoming/modtool/ModtoolReceivedRoomsUserEvent.ts new file mode 100644 index 00000000..3122afbb --- /dev/null +++ b/src/nitro/communication/messages/incoming/modtool/ModtoolReceivedRoomsUserEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { ModtoolRoomUsersParser } from '../../parser/modtool/ModtoolRoomUsersParser'; + +export class ModtoolReceivedRoomsUserEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, ModtoolRoomUsersParser); + } + + public getParser(): ModtoolRoomUsersParser + { + return this.parser as ModtoolRoomUsersParser; + } +} diff --git a/src/nitro/communication/messages/incoming/modtool/ModtoolRoomChatlogEvent.ts b/src/nitro/communication/messages/incoming/modtool/ModtoolRoomChatlogEvent.ts new file mode 100644 index 00000000..1747c21c --- /dev/null +++ b/src/nitro/communication/messages/incoming/modtool/ModtoolRoomChatlogEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { ModtoolRoomChatlogParser } from '../../parser/modtool/ModtoolRoomChatlogParser'; + +export class ModtoolRoomChatlogEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, ModtoolRoomChatlogParser); + } + + public getParser(): ModtoolRoomChatlogParser + { + return this.parser as ModtoolRoomChatlogParser; + } +} diff --git a/src/nitro/communication/messages/incoming/modtool/ModtoolRoomInfoEvent.ts b/src/nitro/communication/messages/incoming/modtool/ModtoolRoomInfoEvent.ts new file mode 100644 index 00000000..5e451978 --- /dev/null +++ b/src/nitro/communication/messages/incoming/modtool/ModtoolRoomInfoEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { ModtoolRoomInfoParser } from '../../parser/modtool/ModtoolRoomInfoParser'; + +export class ModtoolRoomInfoEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, ModtoolRoomInfoParser); + } + + public getParser(): ModtoolRoomInfoParser + { + return this.parser as ModtoolRoomInfoParser; + } +} diff --git a/src/nitro/communication/messages/incoming/modtool/ModtoolUserChatlogEvent.ts b/src/nitro/communication/messages/incoming/modtool/ModtoolUserChatlogEvent.ts new file mode 100644 index 00000000..97553c7c --- /dev/null +++ b/src/nitro/communication/messages/incoming/modtool/ModtoolUserChatlogEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { ModtoolUserChatlogParser } from '../../parser/modtool/ModtoolUserChatlogParser'; + +export class ModtoolUserChatlogEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, ModtoolUserChatlogParser); + } + + public getParser(): ModtoolUserChatlogParser + { + return this.parser as ModtoolUserChatlogParser; + } +} diff --git a/src/nitro/communication/messages/incoming/modtool/ModtoolUserInfoEvent.ts b/src/nitro/communication/messages/incoming/modtool/ModtoolUserInfoEvent.ts new file mode 100644 index 00000000..cd1eaa75 --- /dev/null +++ b/src/nitro/communication/messages/incoming/modtool/ModtoolUserInfoEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { ModtoolUserInfoParser } from '../../parser/modtool/ModtoolUserInfoParser'; + +export class ModtoolUserInfoEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, ModtoolUserInfoParser); + } + + public getParser(): ModtoolUserInfoParser + { + return this.parser as ModtoolUserInfoParser; + } +} diff --git a/src/nitro/communication/messages/incoming/navigator/NavigatorCategoriesEvent.ts b/src/nitro/communication/messages/incoming/navigator/NavigatorCategoriesEvent.ts new file mode 100644 index 00000000..789352dd --- /dev/null +++ b/src/nitro/communication/messages/incoming/navigator/NavigatorCategoriesEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { NavigatorCategoriesParser } from '../../parser/navigator/NavigatorCategoriesParser'; + +export class NavigatorCategoriesEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, NavigatorCategoriesParser); + } + + public getParser(): NavigatorCategoriesParser + { + return this.parser as NavigatorCategoriesParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/navigator/NavigatorCollapsedEvent.ts b/src/nitro/communication/messages/incoming/navigator/NavigatorCollapsedEvent.ts new file mode 100644 index 00000000..eee2e601 --- /dev/null +++ b/src/nitro/communication/messages/incoming/navigator/NavigatorCollapsedEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { NavigatorCollapsedParser } from '../../parser/navigator/NavigatorCollapsedParser'; + +export class NavigatorCollapsedEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, NavigatorCollapsedParser); + } + + public getParser(): NavigatorCollapsedParser + { + return this.parser as NavigatorCollapsedParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/navigator/NavigatorEventCategoriesEvent.ts b/src/nitro/communication/messages/incoming/navigator/NavigatorEventCategoriesEvent.ts new file mode 100644 index 00000000..e83361a0 --- /dev/null +++ b/src/nitro/communication/messages/incoming/navigator/NavigatorEventCategoriesEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { NavigatorEventCategoriesParser } from '../../parser/navigator/NavigatorEventCategoriesParser'; + +export class NavigatorEventCategoriesEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, NavigatorEventCategoriesParser); + } + + public getParser(): NavigatorEventCategoriesParser + { + return this.parser as NavigatorEventCategoriesParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/navigator/NavigatorHomeRoomEvent.ts b/src/nitro/communication/messages/incoming/navigator/NavigatorHomeRoomEvent.ts new file mode 100644 index 00000000..d5a444bd --- /dev/null +++ b/src/nitro/communication/messages/incoming/navigator/NavigatorHomeRoomEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { NavigatorHomeRoomParser } from '../../parser/navigator/NavigatorHomeRoomParser'; + +export class NavigatorHomeRoomEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, NavigatorHomeRoomParser); + } + + public getParser(): NavigatorHomeRoomParser + { + return this.parser as NavigatorHomeRoomParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/navigator/NavigatorLiftedEvent.ts b/src/nitro/communication/messages/incoming/navigator/NavigatorLiftedEvent.ts new file mode 100644 index 00000000..2624106e --- /dev/null +++ b/src/nitro/communication/messages/incoming/navigator/NavigatorLiftedEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { NavigatorLiftedParser } from '../../parser/navigator/NavigatorLiftedParser'; + +export class NavigatorLiftedEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, NavigatorLiftedParser); + } + + public getParser(): NavigatorLiftedParser + { + return this.parser as NavigatorLiftedParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/navigator/NavigatorMetadataEvent.ts b/src/nitro/communication/messages/incoming/navigator/NavigatorMetadataEvent.ts new file mode 100644 index 00000000..44e7224f --- /dev/null +++ b/src/nitro/communication/messages/incoming/navigator/NavigatorMetadataEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { NavigatorMetadataParser } from '../../parser/navigator/NavigatorMetadataParser'; + +export class NavigatorMetadataEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, NavigatorMetadataParser); + } + + public getParser(): NavigatorMetadataParser + { + return this.parser as NavigatorMetadataParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/navigator/NavigatorOpenRoomCreatorEvent.ts b/src/nitro/communication/messages/incoming/navigator/NavigatorOpenRoomCreatorEvent.ts new file mode 100644 index 00000000..0979b5f1 --- /dev/null +++ b/src/nitro/communication/messages/incoming/navigator/NavigatorOpenRoomCreatorEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { NavigatorOpenRoomCreatorParser } from '../../parser/navigator/NavigatorOpenRoomCreatorParser'; + +export class NavigatorOpenRoomCreatorEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, NavigatorOpenRoomCreatorParser); + } + + public getParser(): NavigatorOpenRoomCreatorParser + { + return this.parser as NavigatorOpenRoomCreatorParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/navigator/NavigatorSearchEvent.ts b/src/nitro/communication/messages/incoming/navigator/NavigatorSearchEvent.ts new file mode 100644 index 00000000..5ba3d204 --- /dev/null +++ b/src/nitro/communication/messages/incoming/navigator/NavigatorSearchEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { NavigatorSearchParser } from '../../parser/navigator/NavigatorSearchParser'; + +export class NavigatorSearchEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, NavigatorSearchParser); + } + + public getParser(): NavigatorSearchParser + { + return this.parser as NavigatorSearchParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/navigator/NavigatorSearchesEvent.ts b/src/nitro/communication/messages/incoming/navigator/NavigatorSearchesEvent.ts new file mode 100644 index 00000000..06e8bdad --- /dev/null +++ b/src/nitro/communication/messages/incoming/navigator/NavigatorSearchesEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { NavigatorSearchesParser } from '../../parser/navigator/NavigatorSearchesParser'; + +export class NavigatorSearchesEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, NavigatorSearchesParser); + } + + public getParser(): NavigatorSearchesParser + { + return this.parser as NavigatorSearchesParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/navigator/NavigatorSettingsEvent.ts b/src/nitro/communication/messages/incoming/navigator/NavigatorSettingsEvent.ts new file mode 100644 index 00000000..1e80d52d --- /dev/null +++ b/src/nitro/communication/messages/incoming/navigator/NavigatorSettingsEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { NavigatorSettingsParser } from '../../parser/navigator/NavigatorSettingsParser'; + +export class NavigatorSettingsEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, NavigatorSettingsParser); + } + + public getParser(): NavigatorSettingsParser + { + return this.parser as NavigatorSettingsParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/notifications/BotErrorEvent.ts b/src/nitro/communication/messages/incoming/notifications/BotErrorEvent.ts new file mode 100644 index 00000000..579c71f2 --- /dev/null +++ b/src/nitro/communication/messages/incoming/notifications/BotErrorEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { BotErrorEventParser } from '../../parser/notifications/BotErrorEventParser'; + +export class BotErrorEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, BotErrorEventParser); + } + + public getParser(): BotErrorEventParser + { + return this.parser as BotErrorEventParser; + } +} diff --git a/src/nitro/communication/messages/incoming/notifications/HabboBroadcastMessageEvent.ts b/src/nitro/communication/messages/incoming/notifications/HabboBroadcastMessageEvent.ts new file mode 100644 index 00000000..616c4653 --- /dev/null +++ b/src/nitro/communication/messages/incoming/notifications/HabboBroadcastMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { HabboBroadcastMessageParser } from '../../parser/notifications/HabboBroadcastMessageParser'; + +export class HabboBroadcastMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, HabboBroadcastMessageParser); + } + + public getParser(): HabboBroadcastMessageParser + { + return this.parser as HabboBroadcastMessageParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/notifications/HotelWillShutdownEvent.ts b/src/nitro/communication/messages/incoming/notifications/HotelWillShutdownEvent.ts new file mode 100644 index 00000000..6cc44385 --- /dev/null +++ b/src/nitro/communication/messages/incoming/notifications/HotelWillShutdownEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { HotelWillShutdownParser } from '../../parser/notifications/HotelWillShutdownParser'; + +export class HotelWillShutdownEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, HotelWillShutdownParser); + } + + public getParser(): HotelWillShutdownParser + { + return this.parser as HotelWillShutdownParser; + } +} diff --git a/src/nitro/communication/messages/incoming/notifications/MOTDNotificationEvent.ts b/src/nitro/communication/messages/incoming/notifications/MOTDNotificationEvent.ts new file mode 100644 index 00000000..1bbdca07 --- /dev/null +++ b/src/nitro/communication/messages/incoming/notifications/MOTDNotificationEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { MOTDNotificationParser } from '../../parser/notifications/MOTDNotificationParser'; + +export class MOTDNotificationEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, MOTDNotificationParser); + } + + public getParser(): MOTDNotificationParser + { + return this.parser as MOTDNotificationParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/notifications/NotificationDialogMessageEvent.ts b/src/nitro/communication/messages/incoming/notifications/NotificationDialogMessageEvent.ts new file mode 100644 index 00000000..33b909ea --- /dev/null +++ b/src/nitro/communication/messages/incoming/notifications/NotificationDialogMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { NotificationDialogMessageParser } from '../../parser/notifications/NotificationDialogMessageParser'; + +export class NotificationDialogMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, NotificationDialogMessageParser); + } + + public getParser(): NotificationDialogMessageParser + { + return this.parser as NotificationDialogMessageParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/notifications/PetPlacingErrorEvent.ts b/src/nitro/communication/messages/incoming/notifications/PetPlacingErrorEvent.ts new file mode 100644 index 00000000..a9291352 --- /dev/null +++ b/src/nitro/communication/messages/incoming/notifications/PetPlacingErrorEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { PetPlacingErrorEventParser } from '../../parser/notifications/PetPlacingErrorEventParser'; + +export class PetPlacingErrorEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, PetPlacingErrorEventParser); + } + + public getParser(): PetPlacingErrorEventParser + { + return this.parser as PetPlacingErrorEventParser; + } +} diff --git a/src/nitro/communication/messages/incoming/notifications/RespectReceivedEvent.ts b/src/nitro/communication/messages/incoming/notifications/RespectReceivedEvent.ts new file mode 100644 index 00000000..e67a7f2d --- /dev/null +++ b/src/nitro/communication/messages/incoming/notifications/RespectReceivedEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { RespectReceivedParser } from '../../parser/notifications/RespectReceivedParser'; + +export class RespectReceivedEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RespectReceivedParser); + } + + public getParser(): RespectReceivedParser + { + return this.parser as RespectReceivedParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/notifications/UnseenItemsEvent.ts b/src/nitro/communication/messages/incoming/notifications/UnseenItemsEvent.ts new file mode 100644 index 00000000..0d347fdd --- /dev/null +++ b/src/nitro/communication/messages/incoming/notifications/UnseenItemsEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { UnseenItemsParser } from '../../parser/notifications/UnseenItemsParser'; + +export class UnseenItemsEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, UnseenItemsParser); + } + + public getParser(): UnseenItemsParser + { + return this.parser as UnseenItemsParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/room/access/RoomEnterErrorEvent.ts b/src/nitro/communication/messages/incoming/room/access/RoomEnterErrorEvent.ts new file mode 100644 index 00000000..d959a351 --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/access/RoomEnterErrorEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { RoomEnterErrorParser } from '../../../parser/room/access/RoomEnterErrorParser'; + +export class RoomEnterErrorEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomEnterErrorParser); + } + + public getParser(): RoomEnterErrorParser + { + return this.parser as RoomEnterErrorParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/room/access/RoomEnterEvent.ts b/src/nitro/communication/messages/incoming/room/access/RoomEnterEvent.ts new file mode 100644 index 00000000..c46ee72a --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/access/RoomEnterEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { RoomEnterParser } from '../../../parser/room/access/RoomEnterParser'; + +export class RoomEnterEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomEnterParser); + } + + public getParser(): RoomEnterParser + { + return this.parser as RoomEnterParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/room/access/RoomForwardEvent.ts b/src/nitro/communication/messages/incoming/room/access/RoomForwardEvent.ts new file mode 100644 index 00000000..6d5ac9b3 --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/access/RoomForwardEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { RoomFowardParser as RoomForwardParser } from '../../../parser/room/access/RoomFowardParser'; + +export class RoomForwardEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomForwardParser); + } + + public getParser(): RoomForwardParser + { + return this.parser as RoomForwardParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/room/access/doorbell/RoomDoorbellAcceptedEvent.ts b/src/nitro/communication/messages/incoming/room/access/doorbell/RoomDoorbellAcceptedEvent.ts new file mode 100644 index 00000000..1526dc6b --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/access/doorbell/RoomDoorbellAcceptedEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../../core/communication/messages/MessageEvent'; +import { RoomDoorbellAcceptedParser } from '../../../../parser/room/access/doorbell/RoomDoorbellAcceptedParser'; + +export class RoomDoorbellAcceptedEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomDoorbellAcceptedParser); + } + + public getParser(): RoomDoorbellAcceptedParser + { + return this.parser as RoomDoorbellAcceptedParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/room/access/doorbell/RoomDoorbellEvent.ts b/src/nitro/communication/messages/incoming/room/access/doorbell/RoomDoorbellEvent.ts new file mode 100644 index 00000000..70e698fb --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/access/doorbell/RoomDoorbellEvent.ts @@ -0,0 +1,21 @@ +import { IMessageEvent } from '../../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../../core/communication/messages/MessageEvent'; +import { RoomDoorbellParser } from '../../../../parser/room/access/doorbell/RoomDoorbellParser'; + +export class RoomDoorbellEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomDoorbellParser); + } + + public getParser(): RoomDoorbellParser + { + return this.parser as RoomDoorbellParser; + } + + public get userName(): string + { + return this.getParser().userName; + } +} diff --git a/src/nitro/communication/messages/incoming/room/access/doorbell/RoomDoorbellRejectedEvent.ts b/src/nitro/communication/messages/incoming/room/access/doorbell/RoomDoorbellRejectedEvent.ts new file mode 100644 index 00000000..7547ad44 --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/access/doorbell/RoomDoorbellRejectedEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../../core/communication/messages/MessageEvent'; +import { RoomDoorbellRejectedParser } from '../../../../parser/room/access/doorbell/RoomDoorbellRejectedParser'; + +export class RoomDoorbellRejectedEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomDoorbellRejectedParser); + } + + public getParser(): RoomDoorbellRejectedParser + { + return this.parser as RoomDoorbellRejectedParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/room/access/rights/RoomRightsClearEvent.ts b/src/nitro/communication/messages/incoming/room/access/rights/RoomRightsClearEvent.ts new file mode 100644 index 00000000..0aed6433 --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/access/rights/RoomRightsClearEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../../core/communication/messages/MessageEvent'; +import { RoomRightsClearParser } from '../../../../parser/room/access/rights/RoomRightsClearParser'; + +export class RoomRightsClearEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomRightsClearParser); + } + + public getParser(): RoomRightsClearParser + { + return this.parser as RoomRightsClearParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/room/access/rights/RoomRightsEvent.ts b/src/nitro/communication/messages/incoming/room/access/rights/RoomRightsEvent.ts new file mode 100644 index 00000000..399bcf73 --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/access/rights/RoomRightsEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../../core/communication/messages/MessageEvent'; +import { RoomRightsParser } from '../../../../parser/room/access/rights/RoomRightsParser'; + +export class RoomRightsEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomRightsParser); + } + + public getParser(): RoomRightsParser + { + return this.parser as RoomRightsParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/room/access/rights/RoomRightsOwnerEvent.ts b/src/nitro/communication/messages/incoming/room/access/rights/RoomRightsOwnerEvent.ts new file mode 100644 index 00000000..e846cdc4 --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/access/rights/RoomRightsOwnerEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../../core/communication/messages/MessageEvent'; +import { RoomRightsOwnerParser } from '../../../../parser/room/access/rights/RoomRightsOwnerParser'; + +export class RoomRightsOwnerEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomRightsOwnerParser); + } + + public getParser(): RoomRightsOwnerParser + { + return this.parser as RoomRightsOwnerParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/room/bots/BotCommandConfigurationEvent.ts b/src/nitro/communication/messages/incoming/room/bots/BotCommandConfigurationEvent.ts new file mode 100644 index 00000000..2dfdee94 --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/bots/BotCommandConfigurationEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { BotCommandConfigurationParser } from '../../../parser/room/bots/BotCommandConfigurationParser'; + +export class BotCommandConfigurationEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, BotCommandConfigurationParser); + } + + public getParser(): BotCommandConfigurationParser + { + return this.parser as BotCommandConfigurationParser; + } +} diff --git a/src/nitro/communication/messages/incoming/room/data/RoomBannedUsersEvent.ts b/src/nitro/communication/messages/incoming/room/data/RoomBannedUsersEvent.ts new file mode 100644 index 00000000..f4d56579 --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/data/RoomBannedUsersEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { RoomSettingsUsersListParser } from '../../../parser/room/data/RoomSettingsUsersListParser'; + +export class RoomBannedUsersEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomSettingsUsersListParser); + } + + public getParser(): RoomSettingsUsersListParser + { + return this.parser as RoomSettingsUsersListParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/room/data/RoomChatSettingsEvent.ts b/src/nitro/communication/messages/incoming/room/data/RoomChatSettingsEvent.ts new file mode 100644 index 00000000..407d3224 --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/data/RoomChatSettingsEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { RoomChatSettingsParser } from '../../../parser/room/data/RoomChatSettingsParser'; + +export class RoomChatSettingsEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomChatSettingsParser); + } + + public getParser(): RoomChatSettingsParser + { + return this.parser as RoomChatSettingsParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/room/data/RoomInfoEvent.ts b/src/nitro/communication/messages/incoming/room/data/RoomInfoEvent.ts new file mode 100644 index 00000000..bc84fd70 --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/data/RoomInfoEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { RoomInfoParser } from '../../../parser/room/data/RoomInfoParser'; + +export class RoomInfoEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomInfoParser); + } + + public getParser(): RoomInfoParser + { + return this.parser as RoomInfoParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/room/data/RoomInfoOwnerEvent.ts b/src/nitro/communication/messages/incoming/room/data/RoomInfoOwnerEvent.ts new file mode 100644 index 00000000..bfbfb969 --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/data/RoomInfoOwnerEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { RoomInfoOwnerParser } from '../../../parser/room/data/RoomInfoOwnerParser'; + +export class RoomInfoOwnerEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomInfoOwnerParser); + } + + public getParser(): RoomInfoOwnerParser + { + return this.parser as RoomInfoOwnerParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/room/data/RoomScoreEvent.ts b/src/nitro/communication/messages/incoming/room/data/RoomScoreEvent.ts new file mode 100644 index 00000000..040c408a --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/data/RoomScoreEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { RoomScoreParser } from '../../../parser/room/data/RoomScoreParser'; + +export class RoomScoreEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomScoreParser); + } + + public getParser(): RoomScoreParser + { + return this.parser as RoomScoreParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/room/data/RoomSettingsErrorEvent.ts b/src/nitro/communication/messages/incoming/room/data/RoomSettingsErrorEvent.ts new file mode 100644 index 00000000..589d8db0 --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/data/RoomSettingsErrorEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { RoomSettingsErrorParser } from '../../../parser/room/data/RoomSettingsErrorParser'; + +export class RoomSettingsErrorEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomSettingsErrorParser); + } + + public getParser(): RoomSettingsErrorParser + { + return this.parser as RoomSettingsErrorParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/room/data/RoomSettingsEvent.ts b/src/nitro/communication/messages/incoming/room/data/RoomSettingsEvent.ts new file mode 100644 index 00000000..27deb0e6 --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/data/RoomSettingsEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { RoomSettingsParser } from '../../../parser/room/data/RoomSettingsParser'; + +export class RoomSettingsEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomSettingsParser); + } + + public getParser(): RoomSettingsParser + { + return this.parser as RoomSettingsParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/room/data/RoomSettingsSavedEvent.ts b/src/nitro/communication/messages/incoming/room/data/RoomSettingsSavedEvent.ts new file mode 100644 index 00000000..7b3dbd4c --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/data/RoomSettingsSavedEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { RoomSettingsSavedParser } from '../../../parser/room/data/RoomSettingsSavedParser'; + +export class RoomSettingsSavedEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomSettingsSavedParser); + } + + public getParser(): RoomSettingsSavedParser + { + return this.parser as RoomSettingsSavedParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/room/data/RoomSettingsUpdatedEvent.ts b/src/nitro/communication/messages/incoming/room/data/RoomSettingsUpdatedEvent.ts new file mode 100644 index 00000000..314e7946 --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/data/RoomSettingsUpdatedEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { RoomSettingsUpdatedParser } from '../../../parser/room/data/RoomSettingsUpdatedParser'; + +export class RoomSettingsUpdatedEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomSettingsUpdatedParser); + } + + public getParser(): RoomSettingsUpdatedParser + { + return this.parser as RoomSettingsUpdatedParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/room/data/RoomUsersWithRightsEvent.ts b/src/nitro/communication/messages/incoming/room/data/RoomUsersWithRightsEvent.ts new file mode 100644 index 00000000..b32b8c8a --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/data/RoomUsersWithRightsEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { RoomSettingsUsersListParser } from '../../../parser/room/data/RoomSettingsUsersListParser'; + +export class RoomUsersWithRightsEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomSettingsUsersListParser); + } + + public getParser(): RoomSettingsUsersListParser + { + return this.parser as RoomSettingsUsersListParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/room/engine/ObjectsRollingEvent.ts b/src/nitro/communication/messages/incoming/room/engine/ObjectsRollingEvent.ts new file mode 100644 index 00000000..3576dcff --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/engine/ObjectsRollingEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { ObjectsRollingParser } from '../../../parser/room/engine/ObjectsRollingParser'; + +export class ObjectsRollingEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, ObjectsRollingParser); + } + + public getParser(): ObjectsRollingParser + { + return this.parser as ObjectsRollingParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/room/engine/RoomCreatedEvent.ts b/src/nitro/communication/messages/incoming/room/engine/RoomCreatedEvent.ts new file mode 100644 index 00000000..cfa37558 --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/engine/RoomCreatedEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { RoomCreatedParser } from '../../../parser/room/engine/RoomCreatedParser'; + +export class RoomCreatedEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomCreatedParser); + } + + public getParser(): RoomCreatedParser + { + return this.parser as RoomCreatedParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/room/furniture/FurnitureAliasesEvent.ts b/src/nitro/communication/messages/incoming/room/furniture/FurnitureAliasesEvent.ts new file mode 100644 index 00000000..e36c34ca --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/furniture/FurnitureAliasesEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { FurnitureAliasesParser } from '../../../parser/room/furniture/FurnitureAliasesParser'; + +export class FurnitureAliasesEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FurnitureAliasesParser); + } + + public getParser(): FurnitureAliasesParser + { + return this.parser as FurnitureAliasesParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/room/furniture/FurnitureDataEvent.ts b/src/nitro/communication/messages/incoming/room/furniture/FurnitureDataEvent.ts new file mode 100644 index 00000000..3e7808e6 --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/furniture/FurnitureDataEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { FurnitureDataParser } from '../../../parser/room/furniture/FurnitureDataParser'; + +export class FurnitureDataEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FurnitureDataParser); + } + + public getParser(): FurnitureDataParser + { + return this.parser as FurnitureDataParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/room/furniture/FurnitureItemDataEvent.ts b/src/nitro/communication/messages/incoming/room/furniture/FurnitureItemDataEvent.ts new file mode 100644 index 00000000..a54e8daf --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/furniture/FurnitureItemDataEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { FurnitureItemDataParser } from '../../../parser/room/furniture/FurnitureItemDataParser'; + +export class FurnitureItemDataEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FurnitureItemDataParser); + } + + public getParser(): FurnitureItemDataParser + { + return this.parser as FurnitureItemDataParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/room/furniture/FurnitureStackHeightEvent.ts b/src/nitro/communication/messages/incoming/room/furniture/FurnitureStackHeightEvent.ts new file mode 100644 index 00000000..90a9baa6 --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/furniture/FurnitureStackHeightEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { FurnitureStackHeightParser } from '../../../parser/room/furniture/FurnitureStackHeightParser'; + +export class FurnitureStackHeightEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FurnitureStackHeightParser); + } + + public getParser(): FurnitureStackHeightParser + { + return this.parser as FurnitureStackHeightParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/room/furniture/FurnitureState2Event.ts b/src/nitro/communication/messages/incoming/room/furniture/FurnitureState2Event.ts new file mode 100644 index 00000000..7cc24502 --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/furniture/FurnitureState2Event.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { FurnitureState2Parser } from '../../../parser/room/furniture/FurnitureState2Parser'; + +export class FurnitureState2Event extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FurnitureState2Parser); + } + + public getParser(): FurnitureState2Parser + { + return this.parser as FurnitureState2Parser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/room/furniture/FurnitureStateEvent.ts b/src/nitro/communication/messages/incoming/room/furniture/FurnitureStateEvent.ts new file mode 100644 index 00000000..07b53842 --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/furniture/FurnitureStateEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { FurnitureStateParser } from '../../../parser/room/furniture/FurnitureStateParser'; + +export class FurnitureStateEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FurnitureStateParser); + } + + public getParser(): FurnitureStateParser + { + return this.parser as FurnitureStateParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/room/furniture/LoveLockFurniFinishedEvent.ts b/src/nitro/communication/messages/incoming/room/furniture/LoveLockFurniFinishedEvent.ts new file mode 100644 index 00000000..a8bdf2a7 --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/furniture/LoveLockFurniFinishedEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { LoveLockFurniFinishedParser } from '../../../parser/room/furniture/LoveLockFurniFinishedParser'; + +export class LoveLockFurniFinishedEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, LoveLockFurniFinishedParser); + } + + public getParser(): LoveLockFurniFinishedParser + { + return this.parser as LoveLockFurniFinishedParser; + } +} diff --git a/src/nitro/communication/messages/incoming/room/furniture/LoveLockFurniFriendConfirmedEvent.ts b/src/nitro/communication/messages/incoming/room/furniture/LoveLockFurniFriendConfirmedEvent.ts new file mode 100644 index 00000000..3e279a31 --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/furniture/LoveLockFurniFriendConfirmedEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { LoveLockFurniFriendConfirmedParser } from '../../../parser/room/furniture/LoveLockFurniFriendConfirmedParser'; + +export class LoveLockFurniFriendConfirmedEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, LoveLockFurniFriendConfirmedParser); + } + + public getParser(): LoveLockFurniFriendConfirmedParser + { + return this.parser as LoveLockFurniFriendConfirmedParser; + } +} diff --git a/src/nitro/communication/messages/incoming/room/furniture/LoveLockFurniStartEvent.ts b/src/nitro/communication/messages/incoming/room/furniture/LoveLockFurniStartEvent.ts new file mode 100644 index 00000000..2c6ce083 --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/furniture/LoveLockFurniStartEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { LoveLockFurniStartParser } from '../../../parser/room/furniture/LoveLockFurniStartParser'; + +export class LoveLockFurniStartEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, LoveLockFurniStartParser); + } + + public getParser(): LoveLockFurniStartParser + { + return this.parser as LoveLockFurniStartParser; + } +} diff --git a/src/nitro/communication/messages/incoming/room/furniture/RoomDimmerPresetsMessageEvent.ts b/src/nitro/communication/messages/incoming/room/furniture/RoomDimmerPresetsMessageEvent.ts new file mode 100644 index 00000000..049823d0 --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/furniture/RoomDimmerPresetsMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { RoomDimmerPresetsMessageParser } from '../../../parser/room/furniture/RoomDimmerPresetsMessageParser'; + +export class RoomDimmerPresetsEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomDimmerPresetsMessageParser); + } + + public getParser(): RoomDimmerPresetsMessageParser + { + return this.parser as RoomDimmerPresetsMessageParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/room/furniture/floor/FurnitureFloorAddEvent.ts b/src/nitro/communication/messages/incoming/room/furniture/floor/FurnitureFloorAddEvent.ts new file mode 100644 index 00000000..e4418384 --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/furniture/floor/FurnitureFloorAddEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../../core/communication/messages/MessageEvent'; +import { FurnitureFloorAddParser } from '../../../../parser/room/furniture/floor/FurnitureFloorAddParser'; + +export class FurnitureFloorAddEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FurnitureFloorAddParser); + } + + public getParser(): FurnitureFloorAddParser + { + return this.parser as FurnitureFloorAddParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/room/furniture/floor/FurnitureFloorEvent.ts b/src/nitro/communication/messages/incoming/room/furniture/floor/FurnitureFloorEvent.ts new file mode 100644 index 00000000..64aa7314 --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/furniture/floor/FurnitureFloorEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../../core/communication/messages/MessageEvent'; +import { FurnitureFloorParser } from '../../../../parser/room/furniture/floor/FurnitureFloorParser'; + +export class FurnitureFloorEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FurnitureFloorParser); + } + + public getParser(): FurnitureFloorParser + { + return this.parser as FurnitureFloorParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/room/furniture/floor/FurnitureFloorRemoveEvent.ts b/src/nitro/communication/messages/incoming/room/furniture/floor/FurnitureFloorRemoveEvent.ts new file mode 100644 index 00000000..727a165e --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/furniture/floor/FurnitureFloorRemoveEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../../core/communication/messages/MessageEvent'; +import { FurnitureFloorRemoveParser } from '../../../../parser/room/furniture/floor/FurnitureFloorRemoveParser'; + +export class FurnitureFloorRemoveEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FurnitureFloorRemoveParser); + } + + public getParser(): FurnitureFloorRemoveParser + { + return this.parser as FurnitureFloorRemoveParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/room/furniture/floor/FurnitureFloorUpdateEvent.ts b/src/nitro/communication/messages/incoming/room/furniture/floor/FurnitureFloorUpdateEvent.ts new file mode 100644 index 00000000..245e6aba --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/furniture/floor/FurnitureFloorUpdateEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../../core/communication/messages/MessageEvent'; +import { FurnitureFloorUpdateParser } from '../../../../parser/room/furniture/floor/FurnitureFloorUpdateParser'; + +export class FurnitureFloorUpdateEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FurnitureFloorUpdateParser); + } + + public getParser(): FurnitureFloorUpdateParser + { + return this.parser as FurnitureFloorUpdateParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/room/furniture/moodlightFromServer.ts b/src/nitro/communication/messages/incoming/room/furniture/moodlightFromServer.ts new file mode 100644 index 00000000..0aedc1f9 --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/furniture/moodlightFromServer.ts @@ -0,0 +1,64 @@ +export class MoodlightFromServer +{ + private readonly _id: number = 0; + private _type: number = 0; + private _color: number = 0; + private _intensity: number = 0; + private _isParsed: boolean = false; + private _htmlColor: string = null; + + constructor(k: number) + { + this._id = k; + } + + public parsed(): void + { + this._isParsed = true; + } + + public get id(): number + { + return this._id; + } + + public get type(): number + { + return this._type; + } + + public set type(k: number) + { + if(!this._isParsed) this._type = k; + } + + public get color(): number + { + return this._color; + } + + public set color(k: number) + { + if(!this._isParsed) this._color = k; + } + + public get intensity(): number + { + return this._intensity; + } + + public set intensity(k: number) + { + if(!this._isParsed) this._intensity = k; + } + + public set htmlColor(color: string) + { + this._htmlColor = color; + } + + public get htmlColor(): string + { + return this._htmlColor; + } +} diff --git a/src/nitro/communication/messages/incoming/room/furniture/wall/FurnitureWallAddEvent.ts b/src/nitro/communication/messages/incoming/room/furniture/wall/FurnitureWallAddEvent.ts new file mode 100644 index 00000000..10f6f585 --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/furniture/wall/FurnitureWallAddEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../../core/communication/messages/MessageEvent'; +import { FurnitureWallAddParser } from '../../../../parser/room/furniture/wall/FurnitureWallAddParser'; + +export class FurnitureWallAddEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FurnitureWallAddParser); + } + + public getParser(): FurnitureWallAddParser + { + return this.parser as FurnitureWallAddParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/room/furniture/wall/FurnitureWallEvent.ts b/src/nitro/communication/messages/incoming/room/furniture/wall/FurnitureWallEvent.ts new file mode 100644 index 00000000..46d06b2e --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/furniture/wall/FurnitureWallEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../../core/communication/messages/MessageEvent'; +import { FurnitureWallParser } from '../../../../parser/room/furniture/wall/FurnitureWallParser'; + +export class FurnitureWallEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FurnitureWallParser); + } + + public getParser(): FurnitureWallParser + { + return this.parser as FurnitureWallParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/room/furniture/wall/FurnitureWallRemoveEvent.ts b/src/nitro/communication/messages/incoming/room/furniture/wall/FurnitureWallRemoveEvent.ts new file mode 100644 index 00000000..92840164 --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/furniture/wall/FurnitureWallRemoveEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../../core/communication/messages/MessageEvent'; +import { FurnitureWallRemoveParser } from '../../../../parser/room/furniture/wall/FurnitureWallRemoveParser'; + +export class FurnitureWallRemoveEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FurnitureWallRemoveParser); + } + + public getParser(): FurnitureWallRemoveParser + { + return this.parser as FurnitureWallRemoveParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/room/furniture/wall/FurnitureWallUpdateEvent.ts b/src/nitro/communication/messages/incoming/room/furniture/wall/FurnitureWallUpdateEvent.ts new file mode 100644 index 00000000..86e8f3b9 --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/furniture/wall/FurnitureWallUpdateEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../../core/communication/messages/MessageEvent'; +import { FurnitureWallUpdateParser } from '../../../../parser/room/furniture/wall/FurnitureWallUpdateParser'; + +export class FurnitureWallUpdateEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FurnitureWallUpdateParser); + } + + public getParser(): FurnitureWallUpdateParser + { + return this.parser as FurnitureWallUpdateParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/room/mapping/RoomDoorEvent.ts b/src/nitro/communication/messages/incoming/room/mapping/RoomDoorEvent.ts new file mode 100644 index 00000000..12051a65 --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/mapping/RoomDoorEvent.ts @@ -0,0 +1,16 @@ +import { RoomDoorParser } from '../../../parser/room/mapping/RoomDoorParser'; +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; + +export class RoomDoorEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomDoorParser); + } + + public getParser(): RoomDoorParser + { + return this.parser as RoomDoorParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/room/mapping/RoomHeightMapEvent.ts b/src/nitro/communication/messages/incoming/room/mapping/RoomHeightMapEvent.ts new file mode 100644 index 00000000..48b1cbdf --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/mapping/RoomHeightMapEvent.ts @@ -0,0 +1,16 @@ +import { RoomHeightMapParser } from '../../../parser/room/mapping/RoomHeightMapParser'; +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; + +export class RoomHeightMapEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomHeightMapParser); + } + + public getParser(): RoomHeightMapParser + { + return this.parser as RoomHeightMapParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/room/mapping/RoomHeightMapUpdateEvent.ts b/src/nitro/communication/messages/incoming/room/mapping/RoomHeightMapUpdateEvent.ts new file mode 100644 index 00000000..02cd7c01 --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/mapping/RoomHeightMapUpdateEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { RoomHeightMapUpdateParser } from '../../../parser/room/mapping/RoomHeightMapUpdateParser'; + +export class RoomHeightMapUpdateEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomHeightMapUpdateParser); + } + + public getParser(): RoomHeightMapUpdateParser + { + return this.parser as RoomHeightMapUpdateParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/room/mapping/RoomModelEvent.ts b/src/nitro/communication/messages/incoming/room/mapping/RoomModelEvent.ts new file mode 100644 index 00000000..17ac3cbc --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/mapping/RoomModelEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { RoomModelParser } from '../../../parser/room/mapping/RoomModelParser'; + +export class RoomModelEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomModelParser); + } + + public getParser(): RoomModelParser + { + return this.parser as RoomModelParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/room/mapping/RoomModelNameEvent.ts b/src/nitro/communication/messages/incoming/room/mapping/RoomModelNameEvent.ts new file mode 100644 index 00000000..575ec56a --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/mapping/RoomModelNameEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { RoomModelNameParser } from '../../../parser/room/mapping/RoomModelNameParser'; + +export class RoomModelNameEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomModelNameParser); + } + + public getParser(): RoomModelNameParser + { + return this.parser as RoomModelNameParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/room/mapping/RoomPaintEvent.ts b/src/nitro/communication/messages/incoming/room/mapping/RoomPaintEvent.ts new file mode 100644 index 00000000..9e1597af --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/mapping/RoomPaintEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { RoomPaintParser } from '../../../parser/room/mapping/RoomPaintParser'; + +export class RoomPaintEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomPaintParser); + } + + public getParser(): RoomPaintParser + { + return this.parser as RoomPaintParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/room/mapping/RoomThicknessEvent.ts b/src/nitro/communication/messages/incoming/room/mapping/RoomThicknessEvent.ts new file mode 100644 index 00000000..3ea31011 --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/mapping/RoomThicknessEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { RoomThicknessParser } from '../../../parser/room/mapping/RoomThicknessParser'; + +export class RoomThicknessEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomThicknessParser); + } + + public getParser(): RoomThicknessParser + { + return this.parser as RoomThicknessParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/room/pet/PetFigureUpdateEvent.ts b/src/nitro/communication/messages/incoming/room/pet/PetFigureUpdateEvent.ts new file mode 100644 index 00000000..00a56355 --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/pet/PetFigureUpdateEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { PetFigureUpdateParser } from '../../../parser/room/pet/PetFigureUpdateParser'; + +export class PetFigureUpdateEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, PetFigureUpdateParser); + } + + public getParser(): PetFigureUpdateParser + { + return this.parser as PetFigureUpdateParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/room/pet/PetInfoEvent.ts b/src/nitro/communication/messages/incoming/room/pet/PetInfoEvent.ts new file mode 100644 index 00000000..3372412a --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/pet/PetInfoEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { PetInfoParser } from '../../../parser/room/pet/PetInfoParser'; + +export class PetInfoEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, PetInfoParser); + } + + public getParser(): PetInfoParser + { + return this.parser as PetInfoParser; + } +} diff --git a/src/nitro/communication/messages/incoming/room/pet/_Str_3763.ts b/src/nitro/communication/messages/incoming/room/pet/_Str_3763.ts new file mode 100644 index 00000000..ca1d0f8d --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/pet/_Str_3763.ts @@ -0,0 +1,55 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; + +export class _Str_3763 +{ + private _Str_7992: number; + private _name: string; + private _level: number; + private _figure: string; + private _owner: string; + + constructor(wrapper: IMessageDataWrapper) + { + if(!wrapper) throw new Error('invalid_wrapper'); + + this._Str_7992 = wrapper.readInt(); + this._name = wrapper.readString(); + this._level = wrapper.readInt(); + this._figure = wrapper.readString(); + this._owner = wrapper.readString(); + } + + public dispose():void + { + this._Str_7992 = 0; + this._name = ''; + this._level = 0; + this._figure = ''; + this._owner = ''; + } + + public get _Str_5277(): number + { + return this._Str_7992; + } + + public get name(): string + { + return this._name; + } + + public get level(): number + { + return this._level; + } + + public get figure(): string + { + return this._figure; + } + + public get owner(): string + { + return this._owner; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/room/pet/_Str_5753.ts b/src/nitro/communication/messages/incoming/room/pet/_Str_5753.ts new file mode 100644 index 00000000..a9163d8f --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/pet/_Str_5753.ts @@ -0,0 +1,40 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; + +export class _Str_5753 +{ + private _Str_16211: number; + private _breeds: number[]; + + constructor(wrapper: IMessageDataWrapper) + { + if(!wrapper) throw new Error('invalid_wrapper'); + + this._Str_16211 = wrapper.readInt(); + this._breeds = []; + + let totalCount = wrapper.readInt(); + + while(totalCount > 0) + { + this._breeds.push(wrapper.readInt()); + + totalCount--; + } + } + + public dispose():void + { + this._Str_16211 = -1; + this._breeds = []; + } + + public get _Str_12554(): number + { + return this._Str_16211; + } + + public get breeds(): number[] + { + return this._breeds; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/room/session/YouArePlayingGameEvent.ts b/src/nitro/communication/messages/incoming/room/session/YouArePlayingGameEvent.ts new file mode 100644 index 00000000..a8471056 --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/session/YouArePlayingGameEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { YouArePlayingGameParser } from '../../../parser/room/session/YouArePlayingGameParser'; + +export class YouArePlayingGameEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, YouArePlayingGameParser); + } + + public getParser(): YouArePlayingGameParser + { + return this.parser as YouArePlayingGameParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/room/unit/RoomUnitDanceEvent.ts b/src/nitro/communication/messages/incoming/room/unit/RoomUnitDanceEvent.ts new file mode 100644 index 00000000..0b2ab9d3 --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/unit/RoomUnitDanceEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { RoomUnitDanceParser } from '../../../parser/room/unit/RoomUnitDanceParser'; + +export class RoomUnitDanceEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomUnitDanceParser); + } + + public getParser(): RoomUnitDanceParser + { + return this.parser as RoomUnitDanceParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/room/unit/RoomUnitEffectEvent.ts b/src/nitro/communication/messages/incoming/room/unit/RoomUnitEffectEvent.ts new file mode 100644 index 00000000..213ec52c --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/unit/RoomUnitEffectEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { RoomUnitEffectParser } from '../../../parser/room/unit/RoomUnitEffectParser'; + +export class RoomUnitEffectEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomUnitEffectParser); + } + + public getParser(): RoomUnitEffectParser + { + return this.parser as RoomUnitEffectParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/room/unit/RoomUnitEvent.ts b/src/nitro/communication/messages/incoming/room/unit/RoomUnitEvent.ts new file mode 100644 index 00000000..643afb5f --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/unit/RoomUnitEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { RoomUnitParser } from '../../../parser/room/unit/RoomUnitParser'; + +export class RoomUnitEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomUnitParser); + } + + public getParser(): RoomUnitParser + { + return this.parser as RoomUnitParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/room/unit/RoomUnitExpressionEvent.ts b/src/nitro/communication/messages/incoming/room/unit/RoomUnitExpressionEvent.ts new file mode 100644 index 00000000..36bc3478 --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/unit/RoomUnitExpressionEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { RoomUnitExpressionParser } from '../../../parser/room/unit/RoomUnitExpressionParser'; + +export class RoomUnitExpressionEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomUnitExpressionParser); + } + + public getParser(): RoomUnitExpressionParser + { + return this.parser as RoomUnitExpressionParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/room/unit/RoomUnitHandItemEvent.ts b/src/nitro/communication/messages/incoming/room/unit/RoomUnitHandItemEvent.ts new file mode 100644 index 00000000..e9ad8b58 --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/unit/RoomUnitHandItemEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { RoomUnitHandItemParser } from '../../../parser/room/unit/RoomUnitHandItemParser'; + +export class RoomUnitHandItemEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomUnitHandItemParser); + } + + public getParser(): RoomUnitHandItemParser + { + return this.parser as RoomUnitHandItemParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/room/unit/RoomUnitHandItemReceivedEvent.ts b/src/nitro/communication/messages/incoming/room/unit/RoomUnitHandItemReceivedEvent.ts new file mode 100644 index 00000000..3a0e88a8 --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/unit/RoomUnitHandItemReceivedEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { RoomUnitHandItemReceivedParser } from '../../../parser/room/unit/RoomUnitHandItemReceivedParser'; + +export class RoomUnitHandItemReceivedEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomUnitHandItemReceivedParser); + } + + public getParser(): RoomUnitHandItemReceivedParser + { + return this.parser as RoomUnitHandItemReceivedParser; + } +} diff --git a/src/nitro/communication/messages/incoming/room/unit/RoomUnitIdleEvent.ts b/src/nitro/communication/messages/incoming/room/unit/RoomUnitIdleEvent.ts new file mode 100644 index 00000000..ef7089ff --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/unit/RoomUnitIdleEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { RoomUnitIdleParser } from '../../../parser/room/unit/RoomUnitIdleParser'; + +export class RoomUnitIdleEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomUnitIdleParser); + } + + public getParser(): RoomUnitIdleParser + { + return this.parser as RoomUnitIdleParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/room/unit/RoomUnitInfoEvent.ts b/src/nitro/communication/messages/incoming/room/unit/RoomUnitInfoEvent.ts new file mode 100644 index 00000000..f3dee198 --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/unit/RoomUnitInfoEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { RoomUnitInfoParser } from '../../../parser/room/unit/RoomUnitInfoParser'; + +export class RoomUnitInfoEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomUnitInfoParser); + } + + public getParser(): RoomUnitInfoParser + { + return this.parser as RoomUnitInfoParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/room/unit/RoomUnitNumberEvent.ts b/src/nitro/communication/messages/incoming/room/unit/RoomUnitNumberEvent.ts new file mode 100644 index 00000000..316a82e6 --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/unit/RoomUnitNumberEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { RoomUnitNumberParser } from '../../../parser/room/unit/RoomUnitNumberParser'; + +export class RoomUnitNumberEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomUnitNumberParser); + } + + public getParser(): RoomUnitNumberParser + { + return this.parser as RoomUnitNumberParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/room/unit/RoomUnitRemoveEvent.ts b/src/nitro/communication/messages/incoming/room/unit/RoomUnitRemoveEvent.ts new file mode 100644 index 00000000..3f410a2d --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/unit/RoomUnitRemoveEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { RoomUnitRemoveParser } from '../../../parser/room/unit/RoomUnitRemoveParser'; + +export class RoomUnitRemoveEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomUnitRemoveParser); + } + + public getParser(): RoomUnitRemoveParser + { + return this.parser as RoomUnitRemoveParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/room/unit/RoomUnitStatusEvent.ts b/src/nitro/communication/messages/incoming/room/unit/RoomUnitStatusEvent.ts new file mode 100644 index 00000000..808b184f --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/unit/RoomUnitStatusEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { RoomUnitStatusParser } from '../../../parser/room/unit/RoomUnitStatusParser'; + +export class RoomUnitStatusEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomUnitStatusParser); + } + + public getParser(): RoomUnitStatusParser + { + return this.parser as RoomUnitStatusParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/room/unit/chat/FloodControlEvent.ts b/src/nitro/communication/messages/incoming/room/unit/chat/FloodControlEvent.ts new file mode 100644 index 00000000..54d61dd7 --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/unit/chat/FloodControlEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../../core/communication/messages/MessageEvent'; +import { FloodControlParser } from '../../../../parser/room/unit/chat/FloodControlParser'; + +export class FloodControlEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, FloodControlParser); + } + + public getParser(): FloodControlParser + { + return this.parser as FloodControlParser; + } +} diff --git a/src/nitro/communication/messages/incoming/room/unit/chat/RemainingMuteEvent.ts b/src/nitro/communication/messages/incoming/room/unit/chat/RemainingMuteEvent.ts new file mode 100644 index 00000000..94eb5106 --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/unit/chat/RemainingMuteEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../../core/communication/messages/MessageEvent'; +import { RemainingMuteParser } from '../../../../parser/room/unit/chat/RemainingMuteParser'; + +export class RemainingMuteEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RemainingMuteParser); + } + + public getParser(): RemainingMuteParser + { + return this.parser as RemainingMuteParser; + } +} diff --git a/src/nitro/communication/messages/incoming/room/unit/chat/RoomUnitChatEvent.ts b/src/nitro/communication/messages/incoming/room/unit/chat/RoomUnitChatEvent.ts new file mode 100644 index 00000000..bc5514d7 --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/unit/chat/RoomUnitChatEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../../core/communication/messages/MessageEvent'; +import { RoomUnitChatParser } from '../../../../parser/room/unit/chat/RoomUnitChatParser'; + +export class RoomUnitChatEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomUnitChatParser); + } + + public getParser(): RoomUnitChatParser + { + return this.parser as RoomUnitChatParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/room/unit/chat/RoomUnitChatShoutEvent.ts b/src/nitro/communication/messages/incoming/room/unit/chat/RoomUnitChatShoutEvent.ts new file mode 100644 index 00000000..d6096b4d --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/unit/chat/RoomUnitChatShoutEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../../core/communication/messages/MessageEvent'; +import { RoomUnitChatParser } from '../../../../parser/room/unit/chat/RoomUnitChatParser'; + +export class RoomUnitChatShoutEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomUnitChatParser); + } + + public getParser(): RoomUnitChatParser + { + return this.parser as RoomUnitChatParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/room/unit/chat/RoomUnitChatWhisperEvent.ts b/src/nitro/communication/messages/incoming/room/unit/chat/RoomUnitChatWhisperEvent.ts new file mode 100644 index 00000000..2f2944d0 --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/unit/chat/RoomUnitChatWhisperEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../../core/communication/messages/MessageEvent'; +import { RoomUnitChatParser } from '../../../../parser/room/unit/chat/RoomUnitChatParser'; + +export class RoomUnitChatWhisperEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomUnitChatParser); + } + + public getParser(): RoomUnitChatParser + { + return this.parser as RoomUnitChatParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/room/unit/chat/RoomUnitTypingEvent.ts b/src/nitro/communication/messages/incoming/room/unit/chat/RoomUnitTypingEvent.ts new file mode 100644 index 00000000..159bd502 --- /dev/null +++ b/src/nitro/communication/messages/incoming/room/unit/chat/RoomUnitTypingEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../../core/communication/messages/MessageEvent'; +import { RoomUnitTypingParser } from '../../../../parser/room/unit/chat/RoomUnitTypingParser'; + +export class RoomUnitTypingEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomUnitTypingParser); + } + + public getParser(): RoomUnitTypingParser + { + return this.parser as RoomUnitTypingParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/roomevents/ActionDefinition.ts b/src/nitro/communication/messages/incoming/roomevents/ActionDefinition.ts new file mode 100644 index 00000000..666d6160 --- /dev/null +++ b/src/nitro/communication/messages/incoming/roomevents/ActionDefinition.ts @@ -0,0 +1,47 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { Triggerable } from './Triggerable'; + +export class ActionDefinition extends Triggerable +{ + private _type: number; + private _delayInPulses: number; + private _conflictingTriggers: number[]; + + constructor(wrapper: IMessageDataWrapper) + { + super(wrapper); + + this._conflictingTriggers = []; + this._type = wrapper.readInt(); + this._delayInPulses = wrapper.readInt(); + + let count = wrapper.readInt(); + + while(count > 0) + { + this._conflictingTriggers.push(wrapper.readInt()); + + count--; + } + } + + public get type(): number + { + return this._type; + } + + public get code(): number + { + return this._type; + } + + public get delayInPulses(): number + { + return this._delayInPulses; + } + + public get conflictingTriggers(): number[] + { + return this._conflictingTriggers; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/roomevents/ConditionDefinition.ts b/src/nitro/communication/messages/incoming/roomevents/ConditionDefinition.ts new file mode 100644 index 00000000..2671f6ae --- /dev/null +++ b/src/nitro/communication/messages/incoming/roomevents/ConditionDefinition.ts @@ -0,0 +1,24 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { Triggerable } from './Triggerable'; + +export class ConditionDefinition extends Triggerable +{ + private _type: number; + + constructor(wrapper: IMessageDataWrapper) + { + super(wrapper); + + this._type = wrapper.readInt(); + } + + public get type(): number + { + return this._type; + } + + public get code(): number + { + return this._type; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/roomevents/RoomMutedEvent.ts b/src/nitro/communication/messages/incoming/roomevents/RoomMutedEvent.ts new file mode 100644 index 00000000..bbe27abe --- /dev/null +++ b/src/nitro/communication/messages/incoming/roomevents/RoomMutedEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { RoomMutedParser } from '../../parser/roomevents/RoomMutedParser'; + +export class RoomMutedEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, RoomMutedParser); + } + + public getParser(): RoomMutedParser + { + return this.parser as RoomMutedParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/roomevents/TriggerDefinition.ts b/src/nitro/communication/messages/incoming/roomevents/TriggerDefinition.ts new file mode 100644 index 00000000..5d159426 --- /dev/null +++ b/src/nitro/communication/messages/incoming/roomevents/TriggerDefinition.ts @@ -0,0 +1,40 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { Triggerable } from './Triggerable'; + +export class TriggerDefinition extends Triggerable +{ + private _triggerConf: number; + private _conflictingActions: number[]; + + constructor(wrapper: IMessageDataWrapper) + { + super(wrapper); + + this._conflictingActions = []; + this._triggerConf = wrapper.readInt(); + + let count = wrapper.readInt(); + + while(count > 0) + { + this._conflictingActions.push(wrapper.readInt()); + + count--; + } + } + + public get type(): number + { + return this._triggerConf; + } + + public get code(): number + { + return this._triggerConf; + } + + public get _Str_21837(): number[] + { + return this._conflictingActions; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/roomevents/Triggerable.ts b/src/nitro/communication/messages/incoming/roomevents/Triggerable.ts new file mode 100644 index 00000000..e51a254a --- /dev/null +++ b/src/nitro/communication/messages/incoming/roomevents/Triggerable.ts @@ -0,0 +1,100 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; + +export class Triggerable +{ + private _stuffTypeSelectionEnabled: boolean; + private _furniLimit: number; + private _stuffIds: number[]; + private _id: number; + private _stringParam: string; + private _intParams: number[]; + private _stuffTypeId: number; + private _stuffTypeSelectionCode: number; + + constructor(wrapper: IMessageDataWrapper) + { + this._stuffIds = []; + this._intParams = []; + this._stuffTypeSelectionEnabled = wrapper.readBoolean(); + this._furniLimit = wrapper.readInt(); + + let count = wrapper.readInt(); + + while(count > 0) + { + this._stuffIds.push(wrapper.readInt()); + + count--; + } + + this._stuffTypeId = wrapper.readInt(); + this._id = wrapper.readInt(); + this._stringParam = wrapper.readString(); + + count = wrapper.readInt(); + + while(count > 0) + { + this._intParams.push(wrapper.readInt()); + + count--; + } + + this._stuffTypeSelectionCode = wrapper.readInt(); + } + + public getBoolean(index: number): boolean + { + return (this._intParams[index] === 1); + } + + public get _Str_21824(): boolean + { + return this._stuffTypeSelectionEnabled; + } + + public get _Str_6040(): number + { + return this._stuffTypeSelectionCode; + } + + public set _Str_6040(k: number) + { + this._stuffTypeSelectionCode = k; + } + + public get maximumItemSelectionCount(): number + { + return this._furniLimit; + } + + public get selectedItems(): number[] + { + return this._stuffIds; + } + + public get id(): number + { + return this._id; + } + + public get stringData(): string + { + return this._stringParam; + } + + public get intData(): number[] + { + return this._intParams; + } + + public get code(): number + { + return 0; + } + + public get spriteId(): number + { + return this._stuffTypeId; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/roomevents/WiredFurniActionEvent.ts b/src/nitro/communication/messages/incoming/roomevents/WiredFurniActionEvent.ts new file mode 100644 index 00000000..e20ca83a --- /dev/null +++ b/src/nitro/communication/messages/incoming/roomevents/WiredFurniActionEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { WiredFurniActionParser } from '../../parser/roomevents/WiredFurniActionParser'; + +export class WiredFurniActionEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, WiredFurniActionParser); + } + + public getParser(): WiredFurniActionParser + { + return this.parser as WiredFurniActionParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/roomevents/WiredFurniConditionEvent.ts b/src/nitro/communication/messages/incoming/roomevents/WiredFurniConditionEvent.ts new file mode 100644 index 00000000..4d9a729e --- /dev/null +++ b/src/nitro/communication/messages/incoming/roomevents/WiredFurniConditionEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { WiredFurniConditionParser } from '../../parser/roomevents/WiredFurniConditionParser'; + +export class WiredFurniConditionEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, WiredFurniConditionParser); + } + + public getParser(): WiredFurniConditionParser + { + return this.parser as WiredFurniConditionParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/roomevents/WiredFurniTriggerEvent.ts b/src/nitro/communication/messages/incoming/roomevents/WiredFurniTriggerEvent.ts new file mode 100644 index 00000000..4b4ff095 --- /dev/null +++ b/src/nitro/communication/messages/incoming/roomevents/WiredFurniTriggerEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { WiredFurniTriggerParser } from '../../parser/roomevents/WiredFurniTriggerParser'; + +export class WiredFurniTriggerEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, WiredFurniTriggerParser); + } + + public getParser(): WiredFurniTriggerParser + { + return this.parser as WiredFurniTriggerParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/roomevents/WiredOpenEvent.ts b/src/nitro/communication/messages/incoming/roomevents/WiredOpenEvent.ts new file mode 100644 index 00000000..0824e49d --- /dev/null +++ b/src/nitro/communication/messages/incoming/roomevents/WiredOpenEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { WiredOpenParser } from '../../parser/roomevents/WiredOpenParser'; + +export class WiredOpenEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, WiredOpenParser); + } + + public getParser(): WiredOpenParser + { + return this.parser as WiredOpenParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/roomevents/WiredRewardResultMessageEvent.ts b/src/nitro/communication/messages/incoming/roomevents/WiredRewardResultMessageEvent.ts new file mode 100644 index 00000000..d803f69f --- /dev/null +++ b/src/nitro/communication/messages/incoming/roomevents/WiredRewardResultMessageEvent.ts @@ -0,0 +1,19 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { WiredRewardResultMessageParser } from '../../parser/roomevents/WiredRewardResultMessageParser'; + +export class WiredRewardResultMessageEvent extends MessageEvent implements IMessageEvent +{ + public static _Str_18436: number = 6; + public static _Str_17787: number = 7; + + constructor(callBack: Function) + { + super(callBack, WiredRewardResultMessageParser); + } + + public getParser(): WiredRewardResultMessageParser + { + return this.parser as WiredRewardResultMessageParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/roomevents/WiredSaveSuccessEvent.ts b/src/nitro/communication/messages/incoming/roomevents/WiredSaveSuccessEvent.ts new file mode 100644 index 00000000..02534465 --- /dev/null +++ b/src/nitro/communication/messages/incoming/roomevents/WiredSaveSuccessEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { WiredSaveSuccessParser } from '../../parser/roomevents/WiredSaveSuccessParser'; + +export class WiredSaveSuccessEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, WiredSaveSuccessParser); + } + + public getParser(): WiredSaveSuccessParser + { + return this.parser as WiredSaveSuccessParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/roomevents/WiredValidationErrorEvent.ts b/src/nitro/communication/messages/incoming/roomevents/WiredValidationErrorEvent.ts new file mode 100644 index 00000000..14d09754 --- /dev/null +++ b/src/nitro/communication/messages/incoming/roomevents/WiredValidationErrorEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { WiredValidationErrorParser } from '../../parser/roomevents/WiredValidationErrorParser'; + +export class WiredValidationErrorEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, WiredValidationErrorParser); + } + + public getParser(): WiredValidationErrorParser + { + return this.parser as WiredValidationErrorParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/security/AuthenticatedEvent.ts b/src/nitro/communication/messages/incoming/security/AuthenticatedEvent.ts new file mode 100644 index 00000000..8c01ea30 --- /dev/null +++ b/src/nitro/communication/messages/incoming/security/AuthenticatedEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { AuthenticatedParser } from '../../parser/security/AuthenticatedParser'; + +export class AuthenticatedEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, AuthenticatedParser); + } + + public getParser(): AuthenticatedParser + { + return this.parser as AuthenticatedParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/user/IgnoreResultEvent.ts b/src/nitro/communication/messages/incoming/user/IgnoreResultEvent.ts new file mode 100644 index 00000000..2b700fdd --- /dev/null +++ b/src/nitro/communication/messages/incoming/user/IgnoreResultEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { IgnoreResultParser } from '../../parser/user/IgnoreResultParser'; + +export class IgnoreResultEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, IgnoreResultParser); + } + + public getParser(): IgnoreResultParser + { + return this.parser as IgnoreResultParser; + } +} diff --git a/src/nitro/communication/messages/incoming/user/IgnoredUsersEvent.ts b/src/nitro/communication/messages/incoming/user/IgnoredUsersEvent.ts new file mode 100644 index 00000000..d8ade5c9 --- /dev/null +++ b/src/nitro/communication/messages/incoming/user/IgnoredUsersEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; +import { IgnoredUsersParser } from '../../parser/user/IgnoredUsersParser'; + +export class IgnoredUsersEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, IgnoredUsersParser); + } + + public getParser(): IgnoredUsersParser + { + return this.parser as IgnoredUsersParser; + } +} diff --git a/src/nitro/communication/messages/incoming/user/InClientLinkEvent.ts b/src/nitro/communication/messages/incoming/user/InClientLinkEvent.ts new file mode 100644 index 00000000..76d0bc15 --- /dev/null +++ b/src/nitro/communication/messages/incoming/user/InClientLinkEvent.ts @@ -0,0 +1,16 @@ +import { InClientLinkParser } from '../../parser/user/InClientLinkParser'; +import { IMessageEvent } from '../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../core/communication/messages/MessageEvent'; + +export class InClientLinkEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, InClientLinkParser); + } + + public getParser(): InClientLinkParser + { + return this.parser as InClientLinkParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/user/access/UserPerksEvent.ts b/src/nitro/communication/messages/incoming/user/access/UserPerksEvent.ts new file mode 100644 index 00000000..e921e8d6 --- /dev/null +++ b/src/nitro/communication/messages/incoming/user/access/UserPerksEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { UserPerksParser } from '../../../parser/user/access/UserPerksParser'; + +export class UserPerksEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, UserPerksParser); + } + + public getParser(): UserPerksParser + { + return this.parser as UserPerksParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/user/access/UserPermissionsEvent.ts b/src/nitro/communication/messages/incoming/user/access/UserPermissionsEvent.ts new file mode 100644 index 00000000..73ffd528 --- /dev/null +++ b/src/nitro/communication/messages/incoming/user/access/UserPermissionsEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { UserPermissionsParser } from '../../../parser/user/access/UserPermissionsParser'; + +export class UserPermissionsEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, UserPermissionsParser); + } + + public getParser(): UserPermissionsParser + { + return this.parser as UserPermissionsParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/user/data/UserCurrentBadgesEvent.ts b/src/nitro/communication/messages/incoming/user/data/UserCurrentBadgesEvent.ts new file mode 100644 index 00000000..c9936402 --- /dev/null +++ b/src/nitro/communication/messages/incoming/user/data/UserCurrentBadgesEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { UserCurrentBadgesParser } from '../../../parser/user/data/UserCurrentBadgesParser'; + +export class UserCurrentBadgesEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, UserCurrentBadgesParser); + } + + public getParser(): UserCurrentBadgesParser + { + return this.parser as UserCurrentBadgesParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/user/data/UserFigureEvent.ts b/src/nitro/communication/messages/incoming/user/data/UserFigureEvent.ts new file mode 100644 index 00000000..1bfbd732 --- /dev/null +++ b/src/nitro/communication/messages/incoming/user/data/UserFigureEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { UserFigureParser } from '../../../parser/user/data/UserFigureParser'; + +export class UserFigureEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, UserFigureParser); + } + + public getParser(): UserFigureParser + { + return this.parser as UserFigureParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/user/data/UserInfoEvent.ts b/src/nitro/communication/messages/incoming/user/data/UserInfoEvent.ts new file mode 100644 index 00000000..ffc071e7 --- /dev/null +++ b/src/nitro/communication/messages/incoming/user/data/UserInfoEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { UserInfoParser } from '../../../parser/user/data/UserInfoParser'; + +export class UserInfoEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, UserInfoParser); + } + + public getParser(): UserInfoParser + { + return this.parser as UserInfoParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/user/data/UserNameChangeMessageEvent.ts b/src/nitro/communication/messages/incoming/user/data/UserNameChangeMessageEvent.ts new file mode 100644 index 00000000..2b0d19a8 --- /dev/null +++ b/src/nitro/communication/messages/incoming/user/data/UserNameChangeMessageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { UserNameChangeMessageParser } from '../../../parser/user/data/UserNameChangeMessageParser'; + +export class UserNameChangeMessageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, UserNameChangeMessageParser); + } + + public getParser(): UserNameChangeMessageParser + { + return this.parser as UserNameChangeMessageParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/user/data/UserProfileEvent.ts b/src/nitro/communication/messages/incoming/user/data/UserProfileEvent.ts new file mode 100644 index 00000000..82491aed --- /dev/null +++ b/src/nitro/communication/messages/incoming/user/data/UserProfileEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { UserProfileParser } from '../../../parser/user/data/UserProfileParser'; + +export class UserProfileEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, UserProfileParser); + } + + public getParser(): UserProfileParser + { + return this.parser as UserProfileParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/user/data/UserRelationshipsEvent.ts b/src/nitro/communication/messages/incoming/user/data/UserRelationshipsEvent.ts new file mode 100644 index 00000000..f44e2936 --- /dev/null +++ b/src/nitro/communication/messages/incoming/user/data/UserRelationshipsEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { UserRelationshipsParser } from '../../../parser/user/data/UserRelationshipsParser'; + +export class UserRelationshipsEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, UserRelationshipsParser); + } + + public getParser(): UserRelationshipsParser + { + return this.parser as UserRelationshipsParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/user/data/UserSettingsEvent.ts b/src/nitro/communication/messages/incoming/user/data/UserSettingsEvent.ts new file mode 100644 index 00000000..7add18ac --- /dev/null +++ b/src/nitro/communication/messages/incoming/user/data/UserSettingsEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { UserSettingsParser } from '../../../parser/user/data/UserSettingsParser'; + +export class UserSettingsEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, UserSettingsParser); + } + + public getParser(): UserSettingsParser + { + return this.parser as UserSettingsParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/user/inventory/currency/UserCreditsEvent.ts b/src/nitro/communication/messages/incoming/user/inventory/currency/UserCreditsEvent.ts new file mode 100644 index 00000000..bc2b65c5 --- /dev/null +++ b/src/nitro/communication/messages/incoming/user/inventory/currency/UserCreditsEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../../core/communication/messages/MessageEvent'; +import { UserCreditsParser } from '../../../../parser/user/inventory/currency/UserCreditsParser'; + +export class UserCreditsEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, UserCreditsParser); + } + + public getParser(): UserCreditsParser + { + return this.parser as UserCreditsParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/user/inventory/currency/UserCurrencyEvent.ts b/src/nitro/communication/messages/incoming/user/inventory/currency/UserCurrencyEvent.ts new file mode 100644 index 00000000..6175e1bb --- /dev/null +++ b/src/nitro/communication/messages/incoming/user/inventory/currency/UserCurrencyEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../../core/communication/messages/MessageEvent'; +import { UserCurrencyParser } from '../../../../parser/user/inventory/currency/UserCurrencyParser'; + +export class UserCurrencyEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, UserCurrencyParser); + } + + public getParser(): UserCurrencyParser + { + return this.parser as UserCurrencyParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/user/inventory/currency/UserCurrencyUpdateEvent.ts b/src/nitro/communication/messages/incoming/user/inventory/currency/UserCurrencyUpdateEvent.ts new file mode 100644 index 00000000..a2c4db74 --- /dev/null +++ b/src/nitro/communication/messages/incoming/user/inventory/currency/UserCurrencyUpdateEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../../core/communication/messages/MessageEvent'; +import { UserCurrencyUpdateParser } from '../../../../parser/user/inventory/currency/UserCurrencyUpdateParser'; + +export class UserCurrencyUpdateEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, UserCurrencyUpdateParser); + } + + public getParser(): UserCurrencyUpdateParser + { + return this.parser as UserCurrencyUpdateParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/user/inventory/subscription/UserSubscriptionEvent.ts b/src/nitro/communication/messages/incoming/user/inventory/subscription/UserSubscriptionEvent.ts new file mode 100644 index 00000000..2f370f24 --- /dev/null +++ b/src/nitro/communication/messages/incoming/user/inventory/subscription/UserSubscriptionEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../../core/communication/messages/MessageEvent'; +import { UserSubscriptionParser } from '../../../../parser/user/inventory/subscription/UserSubscriptionParser'; + +export class UserSubscriptionEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, UserSubscriptionParser); + } + + public getParser(): UserSubscriptionParser + { + return this.parser as UserSubscriptionParser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/incoming/user/wardrobe/UserWardrobePageEvent.ts b/src/nitro/communication/messages/incoming/user/wardrobe/UserWardrobePageEvent.ts new file mode 100644 index 00000000..d0d87747 --- /dev/null +++ b/src/nitro/communication/messages/incoming/user/wardrobe/UserWardrobePageEvent.ts @@ -0,0 +1,16 @@ +import { IMessageEvent } from '../../../../../../core/communication/messages/IMessageEvent'; +import { MessageEvent } from '../../../../../../core/communication/messages/MessageEvent'; +import { UserWardrobePageParser } from '../../../parser/user/wardrobe/UserWardrobePageParser'; + +export class UserWardrobePageEvent extends MessageEvent implements IMessageEvent +{ + constructor(callBack: Function) + { + super(callBack, UserWardrobePageParser); + } + + public getParser(): UserWardrobePageParser + { + return this.parser as UserWardrobePageParser; + } +} diff --git a/src/nitro/communication/messages/outgoing/OutgoingHeader.ts b/src/nitro/communication/messages/outgoing/OutgoingHeader.ts new file mode 100644 index 00000000..e7ec4cc1 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/OutgoingHeader.ts @@ -0,0 +1,225 @@ +export class OutgoingHeader +{ + public static ACHIEVEMENT_LIST = 219; + public static BOT_CONFIGURATION = 1986; + public static BOT_PICKUP = 3323; + public static BOT_PLACE = 1592; + public static BOT_SKILL_SAVE = 2624; + public static CAMERA_PRICE = 796; + public static CAMERA_SAVE = 3226; + public static CAMERA_THUMBNAIL = 1982; + public static CATALOG_CLUB = 3285; + public static CATALOG_CLUB_GIFTS = 487; + public static CATALOG_MODE = 1195; + public static CATALOG_PAGE = 412; + public static CATALOG_PURCHASE = 3492; + public static CATALOG_PURCHASE_GIFT = 1411; + public static CATALOG_SEARCH = 2594; + public static CLIENT_LATENCY = 295; + public static CLIENT_LATENCY_MEASURE = 96; + public static CLIENT_POLICY = 26979; + public static CLIENT_PONG = 2596; + public static CLIENT_TOOLBAR_TOGGLE = 2313; + public static CLIENT_VARIABLES = 1053; + public static DESKTOP_CAMPAIGNS = 2912; + public static DESKTOP_NEWS = 1827; + public static DESKTOP_VIEW = 105; + public static DISCOUNT_CONFIG = 223; + public static EVENT_TRACKER = 3457; + public static FIND_FRIENDS = 516; + public static FURNITURE_ALIASES = 3898; + public static FURNITURE_FLOOR_UPDATE = 248; + public static FURNITURE_MULTISTATE = 99; + public static FURNITURE_PICKUP = 3456; + public static FURNITURE_PLACE = 1258; + public static FURNITURE_POSTIT_PLACE = 2248; + public static FURNITURE_RANDOMSTATE = 3617; + public static FURNITURE_WALL_MULTISTATE = 210; + public static FURNITURE_WALL_UPDATE = 168; + public static GAMES_INIT = 2914; + public static GAMES_LIST = 741; + public static GIFT_CONFIG = 418; + public static GROUP_ADMIN_ADD = 2894; + public static GROUP_ADMIN_REMOVE = 722; + public static GROUP_CREATE_OPTIONS = 798; + public static GROUP_FORUM_INFO = 3149; + public static GROUP_FORUM_LIST = 873; + public static GROUP_FORUM_THREADS = 436; + public static GROUP_INFO = 2991; + public static GROUP_DELETE = 1134; + public static GROUP_MEMBER_REMOVE_CONFIRM = 3593; + public static GROUP_MEMBER_REMOVE = 593; + public static GROUP_MEMBERS = 312; + public static GROUP_MEMBERSHIPS = 367; + public static GROUP_REQUEST = 998; + public static GROUP_REQUEST_ACCEPT = 3386; + public static GROUP_REQUEST_DECLINE = 1894; + public static GROUP_SETTINGS = 1004; + public static GROUP_PARTS = 813; + public static GROUP_BUY = 230; + public static GROUP_SAVE_INFORMATION = 3137; + public static GROUP_SAVE_BADGE = 1991; + public static GROUP_SAVE_COLORS = 1764; + public static GROUP_SAVE_PREFERENCES = 3435; + public static INVENTORY_UNKNOWN = 1371; + public static ITEM_CLOTHING_REDEEM = 3374; + public static ITEM_COLOR_WHEEL_CLICK = 2144; + public static ITEM_DICE_CLICK = 1990; + public static ITEM_DICE_CLOSE = 1533; + public static ITEM_DIMMER_SAVE = 1648; + public static ITEM_DIMMER_SETTINGS = 2813; + public static ITEM_DIMMER_TOGGLE = 2296; + public static ITEM_EXCHANGE_REDEEM = 3115; + public static ITEM_PAINT = 711; + public static ITEM_SAVE_BACKGROUND = 3608; + public static ITEM_STACK_HELPER = 3839; + public static ITEM_WALL_CLICK = 210; + public static ITEM_WALL_UPDATE = 168; + public static MARKETPLACE_CONFIG = 2597; + public static MESSENGER_ACCEPT = 137; + public static MESSENGER_CHAT = 3567; + public static MESSENGER_DECLINE = 2890; + public static MESSENGER_FOLLOW = 3997; + public static MESSENGER_FRIENDS = 1523; + public static MESSENGER_INIT = 2781; + public static MESSENGER_RELATIONSHIPS = 2138; + public static MESSENGER_RELATIONSHIPS_UPDATE = 3768; + public static MESSENGER_REMOVE = 1689; + public static MESSENGER_REQUEST = 3157; + public static MESSENGER_REQUESTS = 2448; + public static MESSENGER_ROOM_INVITE = 1276; + public static MESSENGER_SEARCH = 1210; + public static MESSENGER_UPDATES = 1419; + public static MOD_TOOL_USER_INFO = 3295; + public static NAVIGATOR_CATEGORIES = 3027; + public static NAVIGATOR_INIT = 2110; + public static NAVIGATOR_SEARCH = 249; + public static NAVIGATOR_SEARCH_CLOSE = 1834; + public static NAVIGATOR_SEARCH_OPEN = 637; + public static NAVIGATOR_SEARCH_SAVE = 2226; + public static NAVIGATOR_SETTINGS = 1782; + public static NAVIGATOR_SETTINGS_SAVE = 3159; + public static NAVIGATOR_CATEGORY_LIST_MODE = 1202; + public static PET_INFO = 2934; + public static PET_PICKUP = 1581; + public static PET_PLACE = 2647; + public static PET_RESPECT = 3202; + public static PET_RIDE = 1036; + public static PET_MOVE = 3449; + public static RECYCLER_PRIZES = 398; + public static RELEASE_VERSION = 4000; + public static REPORT = 1691; + public static ROOM_AMBASSADOR_ALERT = 2996; + public static ROOM_BAN_GIVE = 1477; + public static ROOM_BAN_LIST = 2267; + public static ROOM_BAN_REMOVE = 992; + public static ROOM_CREATE = 2752; + public static ROOM_DELETE = 532; + public static ROOM_DOORBELL = 1644; + public static ROOM_ENTER = 2312; + public static ROOM_FAVORITE = 3817; + public static ROOM_FAVORITE_REMOVE = 309; + public static ROOM_INFO = 2230; + public static ROOM_KICK = 1320; + public static ROOM_LIKE = 3582; + public static ROOM_MODEL = 2300; + public static ROOM_MODEL_BLOCKED_TILES = 1687; + public static ROOM_MODEL_DOOR = 3559; + public static ROOM_MODEL_SAVE = 875; + public static ROOM_MUTE = 3637; + public static ROOM_MUTE_USER = 3485; + public static ROOM_RIGHTS_GIVE = 808; + public static ROOM_RIGHTS_LIST = 3385; + public static ROOM_RIGHTS_REMOVE = 2064; + public static ROOM_RIGHTS_REMOVE_ALL = 2683; + public static ROOM_RIGHTS_REMOVE_OWN = 3182; + public static ROOM_SETTINGS = 3129; + public static ROOM_SETTINGS_SAVE = 1969; + public static ROOM_STAFF_PICK = 1918; + public static SECURITY_MACHINE = 2490; + public static SECURITY_TICKET = 2419; + public static TRADE = 1481; + public static TRADE_ACCEPT = 3863; + public static TRADE_CANCEL = 2341; + public static TRADE_CLOSE = 2551; + public static TRADE_CONFIRM = 2760; + public static TRADE_ITEM = 3107; + public static TRADE_ITEM_REMOVE = 3845; + public static TRADE_ITEMS = 1263; + public static TRADE_UNACCEPT = 1444; + public static UNIT_ACTION = 2456; + public static UNIT_CHAT = 1314; + public static UNIT_CHAT_SHOUT = 2085; + public static UNIT_CHAT_WHISPER = 1543; + public static UNIT_DANCE = 2080; + public static UNIT_DROP_HAND_ITEM = 2814; + public static UNIT_GIVE_HANDITEM = 2941; + public static UNIT_LOOK = 3301; + public static UNIT_POSTURE = 2235; + public static UNIT_SIGN = 1975; + public static UNIT_TYPING = 1597; + public static UNIT_TYPING_STOP = 1474; + public static UNIT_WALK = 3320; + public static USER_BADGES = 2769; + public static USER_BADGES_CURRENT = 2091; + public static USER_BADGES_CURRENT_UPDATE = 644; + public static USER_BOTS = 3848; + public static USER_CURRENCY = 273; + public static USER_EFFECT_ACTIVATE = 2959; + public static USER_EFFECT_ENABLE = 1752; + public static USER_FIGURE = 2730; + public static USER_FURNITURE = 3150; // sent when in room + public static USER_FURNITURE2 = 3500; // sent when not in room + public static USER_HOME_ROOM = 1740; + public static USER_INFO = 357; + public static USER_MOTTO = 2228; + public static USER_IGNORED = 3878; + public static USER_OUTFIT_SAVE = 800; + public static USER_OUTFITS = 2742; + public static USER_PETS = 3095; + public static USER_PROFILE = 3265; + public static USER_RESPECT = 2694; + public static USER_SETTINGS = 2388; + public static USER_SETTINGS_CAMERA = 1461; + public static USER_SETTINGS_CHAT_STYLE = 1030; + public static USER_SETTINGS_INVITES = 1086; + public static USER_SETTINGS_OLD_CHAT = 1262; + public static USER_SETTINGS_VOLUME = 1367; + public static USER_SUBSCRIPTION = 3166; + public static USER_WARDROBE_PAGE = 2742; + public static USER_WARDROBE_SAVE = 800; + public static USER_TAGS = 17; + public static USER_VISIT = 2970; + public static WIRED_ACTION_SAVE = 2281; + public static WIRED_APPLY_SNAPSHOT = 3373; + public static WIRED_CONDITION_SAVE = 3203; + public static WIRED_OPEN = 768; + public static WIRED_TRIGGER_SAVE = 1520; + public static GET_ITEM_DATA = 3964; + public static ONE_WAY_DOOR_CLICK = 2765; + public static REMOVE_WALL_ITEM = 3336; + public static MODIFY_WALL_ITEM_DATA = 3666; + public static CATALOG_REDEEM_VOUCHER = 339; + public static ROOM_TONER_APPLY = 2880; + public static LOVELOCK_START_CONFIRM = 3775; + public static MANNEQUIN_SAVE_NAME = 2850; + public static MANNEQUIN_SAVE_LOOK = 2209; + public static PRESENT_OPEN_PRESENT = 3558; + public static CATALOG_SELECT_VIP_GIFT = 2276; + public static USER_IGNORE_ID = 3314; + public static USER_IGNORE = 1117; + public static USER_UNIGNORE = 2061; + public static MODTOOL_REQUEST_ROOM_INFO = 707; + public static MODTOOL_CHANGE_ROOM_SETTINGS = 3260; + public static MODTOOL_REQUEST_USER_CHATLOG = 1391; + public static MODTOOL_REQUEST_ROOM_CHATLOG = 2587; + public static MODTOOL_SANCTION_ALERT = 229; + public static MODTOOL_SANCTION_BAN = 2766; + public static MODTOOL_SANCTION_KICK = 2582; + public static MODTOOL_SANCTION_TRADELOCK = 3742; + public static MODTOOL_ALERTEVENT = 1840; + public static MODTOOL_SANCTION_MUTE = 1945; + public static MODTOOL_REQUEST_USER_ROOMS = 3526; + public static MODTOOL_ROOM_ALERT = 3842; + public static CONVERT_GLOBAL_ROOM_ID = 314; +} diff --git a/src/nitro/communication/messages/outgoing/achievements/RequestAchievementsMessageComposer.ts b/src/nitro/communication/messages/outgoing/achievements/RequestAchievementsMessageComposer.ts new file mode 100644 index 00000000..a3f6403a --- /dev/null +++ b/src/nitro/communication/messages/outgoing/achievements/RequestAchievementsMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class RequestAchievementsMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/catalog/CatalogGroupsComposer.ts b/src/nitro/communication/messages/outgoing/catalog/CatalogGroupsComposer.ts new file mode 100644 index 00000000..171a6e1a --- /dev/null +++ b/src/nitro/communication/messages/outgoing/catalog/CatalogGroupsComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class CatalogGroupsComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/outgoing/catalog/CatalogModeComposer.ts b/src/nitro/communication/messages/outgoing/catalog/CatalogModeComposer.ts new file mode 100644 index 00000000..dd37048c --- /dev/null +++ b/src/nitro/communication/messages/outgoing/catalog/CatalogModeComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class CatalogModeComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(mode: string) + { + this._data = [ mode ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/catalog/CatalogPageComposer.ts b/src/nitro/communication/messages/outgoing/catalog/CatalogPageComposer.ts new file mode 100644 index 00000000..9e55bd0e --- /dev/null +++ b/src/nitro/communication/messages/outgoing/catalog/CatalogPageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class CatalogPageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(pageId: number, offerId: number, catalogType: string) + { + this._data = [ pageId, offerId, catalogType ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/catalog/CatalogPurchaseComposer.ts b/src/nitro/communication/messages/outgoing/catalog/CatalogPurchaseComposer.ts new file mode 100644 index 00000000..413b255a --- /dev/null +++ b/src/nitro/communication/messages/outgoing/catalog/CatalogPurchaseComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class CatalogPurchaseComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(pageId: number, offerId: number, extraData: string, amount: number) + { + this._data = [ pageId, offerId, extraData, amount ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/catalog/CatalogPurchaseGiftComposer.ts b/src/nitro/communication/messages/outgoing/catalog/CatalogPurchaseGiftComposer.ts new file mode 100644 index 00000000..5e3197c4 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/catalog/CatalogPurchaseGiftComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class CatalogPurchaseGiftComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(pageId: number, itemId: number, extraData: string, receivingName: string, giftMessage: string, spriteId: number, color: number, ribbonId: number, anonymousGift: boolean) + { + this._data = [pageId, itemId, extraData, receivingName, giftMessage, spriteId, color, ribbonId, anonymousGift]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/outgoing/catalog/CatalogRequestGiftConfigurationComposer.ts b/src/nitro/communication/messages/outgoing/catalog/CatalogRequestGiftConfigurationComposer.ts new file mode 100644 index 00000000..e9cf6cf4 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/catalog/CatalogRequestGiftConfigurationComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class CatalogRequestGiftConfigurationComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/outgoing/catalog/CatalogRequestVipGiftsComposer.ts b/src/nitro/communication/messages/outgoing/catalog/CatalogRequestVipGiftsComposer.ts new file mode 100644 index 00000000..7d50cca9 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/catalog/CatalogRequestVipGiftsComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class CatalogRequestVipGiftsComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = [ ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + this._data = null; + } +} diff --git a/src/nitro/communication/messages/outgoing/catalog/CatalogRequestVipOffersComposer.ts b/src/nitro/communication/messages/outgoing/catalog/CatalogRequestVipOffersComposer.ts new file mode 100644 index 00000000..29c405a5 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/catalog/CatalogRequestVipOffersComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class CatalogRequestVipOffersComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(offerId: number) + { + this._data = [ offerId ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + this._data = null; + } +} diff --git a/src/nitro/communication/messages/outgoing/catalog/CatalogSearchComposer.ts b/src/nitro/communication/messages/outgoing/catalog/CatalogSearchComposer.ts new file mode 100644 index 00000000..9f15bdf7 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/catalog/CatalogSearchComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class CatalogSearchComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(offerId: number) + { + this._data = [ offerId ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/catalog/CatalogSelectClubGiftComposer.ts b/src/nitro/communication/messages/outgoing/catalog/CatalogSelectClubGiftComposer.ts new file mode 100644 index 00000000..58d09a5d --- /dev/null +++ b/src/nitro/communication/messages/outgoing/catalog/CatalogSelectClubGiftComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class CatalogSelectClubGiftComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(itemName: string) + { + this._data = [ itemName ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/outgoing/catalog/RedeemItemClothingComposer.ts b/src/nitro/communication/messages/outgoing/catalog/RedeemItemClothingComposer.ts new file mode 100644 index 00000000..2aa3f80c --- /dev/null +++ b/src/nitro/communication/messages/outgoing/catalog/RedeemItemClothingComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class RedeemItemClothingComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(setId: number) + { + this._data = [ setId ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/catalog/RedeemVoucherComposer.ts b/src/nitro/communication/messages/outgoing/catalog/RedeemVoucherComposer.ts new file mode 100644 index 00000000..870910ec --- /dev/null +++ b/src/nitro/communication/messages/outgoing/catalog/RedeemVoucherComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class CatalogRedeemVoucherComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(voucherCode: string) + { + this._data = [ voucherCode ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/outgoing/client/ClientPongComposer.ts b/src/nitro/communication/messages/outgoing/client/ClientPongComposer.ts new file mode 100644 index 00000000..10a68f84 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/client/ClientPongComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class ClientPongComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/client/ClientReleaseVersionComposer.ts b/src/nitro/communication/messages/outgoing/client/ClientReleaseVersionComposer.ts new file mode 100644 index 00000000..876b9788 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/client/ClientReleaseVersionComposer.ts @@ -0,0 +1,24 @@ +import { ClientDeviceCategoryEnum } from '../../../../../core/communication/connections/enums/ClientDeviceCategoryEnum'; +import { ClientPlatformEnum } from '../../../../../core/communication/connections/enums/ClientPlatformEnum'; +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; +import { Nitro } from '../../../../Nitro'; + +export class ClientReleaseVersionComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(releaseVersion: string, type: string, platform: number, category: number) + { + this._data = [ Nitro.RELEASE_VERSION, 'HTML5', ClientPlatformEnum.HTML5, ClientDeviceCategoryEnum.BROWSER ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/outgoing/desktop/DesktopViewComposer.ts b/src/nitro/communication/messages/outgoing/desktop/DesktopViewComposer.ts new file mode 100644 index 00000000..77998d48 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/desktop/DesktopViewComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class DesktopViewComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/friendlist/AcceptFriendComposer.ts b/src/nitro/communication/messages/outgoing/friendlist/AcceptFriendComposer.ts new file mode 100644 index 00000000..dee8bd7a --- /dev/null +++ b/src/nitro/communication/messages/outgoing/friendlist/AcceptFriendComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class AcceptFriendComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(...userIds: number[]) + { + this._data = [ userIds.length, ...userIds ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/friendlist/DeclineFriendComposer.ts b/src/nitro/communication/messages/outgoing/friendlist/DeclineFriendComposer.ts new file mode 100644 index 00000000..4ecd6dad --- /dev/null +++ b/src/nitro/communication/messages/outgoing/friendlist/DeclineFriendComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class DeclineFriendComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(removeAll: boolean, ...userIds: number[]) + { + this._data = [ removeAll, userIds.length, ...userIds ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/friendlist/FindNewFriendsComposer.ts b/src/nitro/communication/messages/outgoing/friendlist/FindNewFriendsComposer.ts new file mode 100644 index 00000000..936ce7b5 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/friendlist/FindNewFriendsComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class FindNewFriendsComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/friendlist/FollowFriendComposer.ts b/src/nitro/communication/messages/outgoing/friendlist/FollowFriendComposer.ts new file mode 100644 index 00000000..f4e96cda --- /dev/null +++ b/src/nitro/communication/messages/outgoing/friendlist/FollowFriendComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class FollowFriendComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(userId: number) + { + this._data = [ userId ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/friendlist/FriendListUpdateComposer.ts b/src/nitro/communication/messages/outgoing/friendlist/FriendListUpdateComposer.ts new file mode 100644 index 00000000..dcc4d856 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/friendlist/FriendListUpdateComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class FriendListUpdateComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/friendlist/GetFriendRequestsComposer.ts b/src/nitro/communication/messages/outgoing/friendlist/GetFriendRequestsComposer.ts new file mode 100644 index 00000000..193c55f6 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/friendlist/GetFriendRequestsComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class GetFriendRequestsComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/friendlist/HabboSearchComposer.ts b/src/nitro/communication/messages/outgoing/friendlist/HabboSearchComposer.ts new file mode 100644 index 00000000..0452c199 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/friendlist/HabboSearchComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class HabboSearchComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(search: string) + { + this._data = [ search ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/friendlist/MessengerInitComposer.ts b/src/nitro/communication/messages/outgoing/friendlist/MessengerInitComposer.ts new file mode 100644 index 00000000..c2eb5df6 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/friendlist/MessengerInitComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class MessengerInitComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/friendlist/RemoveFriendComposer.ts b/src/nitro/communication/messages/outgoing/friendlist/RemoveFriendComposer.ts new file mode 100644 index 00000000..b1b09cf9 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/friendlist/RemoveFriendComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class RemoveFriendComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(...userIds: number[]) + { + this._data = [ userIds.length, ...userIds ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/friendlist/RequestFriendComposer.ts b/src/nitro/communication/messages/outgoing/friendlist/RequestFriendComposer.ts new file mode 100644 index 00000000..4dc10701 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/friendlist/RequestFriendComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class RequestFriendComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(username: string) + { + this._data = [ username ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/friendlist/SendMessageComposer.ts b/src/nitro/communication/messages/outgoing/friendlist/SendMessageComposer.ts new file mode 100644 index 00000000..c05ff153 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/friendlist/SendMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class SendMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(userId: number, message: string) + { + this._data = [ userId, message ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/friendlist/SendRoomInviteComposer.ts b/src/nitro/communication/messages/outgoing/friendlist/SendRoomInviteComposer.ts new file mode 100644 index 00000000..10958e78 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/friendlist/SendRoomInviteComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class SendRoomInviteComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(message: string, ...userIds: number[]) + { + this._data = [ message, userIds.length, ...userIds ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/friendlist/SetRelationshipStatusComposer.ts b/src/nitro/communication/messages/outgoing/friendlist/SetRelationshipStatusComposer.ts new file mode 100644 index 00000000..14e83b95 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/friendlist/SetRelationshipStatusComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class SetRelationshipStatusComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(userId: number, relationship: number) + { + this._data = [ userId, relationship ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/friendlist/VisitUserComposer.ts b/src/nitro/communication/messages/outgoing/friendlist/VisitUserComposer.ts new file mode 100644 index 00000000..46da4924 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/friendlist/VisitUserComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class VisitUserComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(username: string) + { + this._data = [ username ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/group/GroupAdminGiveComposer.ts b/src/nitro/communication/messages/outgoing/group/GroupAdminGiveComposer.ts new file mode 100644 index 00000000..e69bb8a1 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/group/GroupAdminGiveComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class GroupAdminGiveComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(groupId: number, memberId: number) + { + this._data = [ groupId, memberId ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/group/GroupAdminTakeComposer.ts b/src/nitro/communication/messages/outgoing/group/GroupAdminTakeComposer.ts new file mode 100644 index 00000000..7af6ccca --- /dev/null +++ b/src/nitro/communication/messages/outgoing/group/GroupAdminTakeComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class GroupAdminTakeComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(groupId: number, memberId: number) + { + this._data = [ groupId, memberId ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/group/GroupBadgePartsComposer.ts b/src/nitro/communication/messages/outgoing/group/GroupBadgePartsComposer.ts new file mode 100644 index 00000000..5fdb39b2 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/group/GroupBadgePartsComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class GroupBadgePartsComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/outgoing/group/GroupBuyComposer.ts b/src/nitro/communication/messages/outgoing/group/GroupBuyComposer.ts new file mode 100644 index 00000000..38e1662a --- /dev/null +++ b/src/nitro/communication/messages/outgoing/group/GroupBuyComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class GroupBuyComposer implements IMessageComposer +{ + private _data: any[]; + + constructor(name: string, description: string, roomId: number, colorA: number, colorB: number, badge: number[]) + { + this._data = [ name, description, roomId, colorA, colorB, badge.length, badge ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/outgoing/group/GroupBuyDataComposer.ts b/src/nitro/communication/messages/outgoing/group/GroupBuyDataComposer.ts new file mode 100644 index 00000000..99db1c84 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/group/GroupBuyDataComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class GroupBuyDataComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/outgoing/group/GroupConfirmRemoveMemberComposer.ts b/src/nitro/communication/messages/outgoing/group/GroupConfirmRemoveMemberComposer.ts new file mode 100644 index 00000000..6cacfa10 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/group/GroupConfirmRemoveMemberComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class GroupConfirmRemoveMemberComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(groupId: number, memberId: number) + { + this._data = [ groupId, memberId ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/group/GroupDeleteComposer.ts b/src/nitro/communication/messages/outgoing/group/GroupDeleteComposer.ts new file mode 100644 index 00000000..74c55e0b --- /dev/null +++ b/src/nitro/communication/messages/outgoing/group/GroupDeleteComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class GroupDeleteComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(groupId: number) + { + this._data = [ groupId ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/group/GroupInformationComposer.ts b/src/nitro/communication/messages/outgoing/group/GroupInformationComposer.ts new file mode 100644 index 00000000..0f67c5ac --- /dev/null +++ b/src/nitro/communication/messages/outgoing/group/GroupInformationComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class GroupInformationComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(groupId: number, flag: boolean) + { + this._data = [ groupId, flag ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/group/GroupJoinComposer.ts b/src/nitro/communication/messages/outgoing/group/GroupJoinComposer.ts new file mode 100644 index 00000000..e5be889c --- /dev/null +++ b/src/nitro/communication/messages/outgoing/group/GroupJoinComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class GroupJoinComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(groupId: number) + { + this._data = [ groupId ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/group/GroupMembersComposer.ts b/src/nitro/communication/messages/outgoing/group/GroupMembersComposer.ts new file mode 100644 index 00000000..d7cd91dc --- /dev/null +++ b/src/nitro/communication/messages/outgoing/group/GroupMembersComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class GroupMembersComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(groupId: number, pageId: number, query: string, levelId: number) + { + this._data = [ groupId, pageId, query, levelId ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/group/GroupMembershipAcceptComposer.ts b/src/nitro/communication/messages/outgoing/group/GroupMembershipAcceptComposer.ts new file mode 100644 index 00000000..b56affb0 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/group/GroupMembershipAcceptComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class GroupMembershipAcceptComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(groupId: number, memberId: number) + { + this._data = [ groupId, memberId ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/group/GroupMembershipDeclineComposer.ts b/src/nitro/communication/messages/outgoing/group/GroupMembershipDeclineComposer.ts new file mode 100644 index 00000000..fff18378 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/group/GroupMembershipDeclineComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class GroupMembershipDeclineComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(groupId: number, memberId: number) + { + this._data = [ groupId, memberId ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/group/GroupRemoveMemberComposer.ts b/src/nitro/communication/messages/outgoing/group/GroupRemoveMemberComposer.ts new file mode 100644 index 00000000..8c656c75 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/group/GroupRemoveMemberComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class GroupRemoveMemberComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(groupId: number, memberId: number) + { + this._data = [ groupId, memberId ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/group/GroupSaveBadgeComposer.ts b/src/nitro/communication/messages/outgoing/group/GroupSaveBadgeComposer.ts new file mode 100644 index 00000000..ab04369e --- /dev/null +++ b/src/nitro/communication/messages/outgoing/group/GroupSaveBadgeComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class GroupSaveBadgeComposer implements IMessageComposer +{ + private _data: any[]; + + constructor(groupId: number, badge: number[]) + { + this._data = [ groupId, badge.length, ...badge ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/outgoing/group/GroupSaveColorsComposer.ts b/src/nitro/communication/messages/outgoing/group/GroupSaveColorsComposer.ts new file mode 100644 index 00000000..45879c81 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/group/GroupSaveColorsComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class GroupSaveColorsComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(groupId: number, colorA: number, colorB: number) + { + this._data = [ groupId, colorA, colorB ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/outgoing/group/GroupSaveInformationComposer.ts b/src/nitro/communication/messages/outgoing/group/GroupSaveInformationComposer.ts new file mode 100644 index 00000000..b45ce938 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/group/GroupSaveInformationComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class GroupSaveInformationComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(groupId: number, title: string, description: string) + { + this._data = [ groupId, title, description ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/outgoing/group/GroupSavePreferencesComposer.ts b/src/nitro/communication/messages/outgoing/group/GroupSavePreferencesComposer.ts new file mode 100644 index 00000000..8a018a52 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/group/GroupSavePreferencesComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class GroupSavePreferencesComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(groupId: number, state: number, onlyAdminCanDecorate: number) + { + this._data = [ groupId, state, onlyAdminCanDecorate ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/outgoing/group/GroupSettingsComposer.ts b/src/nitro/communication/messages/outgoing/group/GroupSettingsComposer.ts new file mode 100644 index 00000000..24564726 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/group/GroupSettingsComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class GroupSettingsComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(groupId: number) + { + this._data = [ groupId ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/outgoing/handshake/InfoRetrieveBaseMessageComposer.ts b/src/nitro/communication/messages/outgoing/handshake/InfoRetrieveBaseMessageComposer.ts new file mode 100644 index 00000000..1a133511 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/handshake/InfoRetrieveBaseMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class InfoRetrieveBaseMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/handshake/SecurityTicketComposer.ts b/src/nitro/communication/messages/outgoing/handshake/SecurityTicketComposer.ts new file mode 100644 index 00000000..f041840d --- /dev/null +++ b/src/nitro/communication/messages/outgoing/handshake/SecurityTicketComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class SecurityTicketComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(ticket: string, time: number) + { + this._data = [ ticket, time ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/inventory/badges/RequestBadgesComposer.ts b/src/nitro/communication/messages/outgoing/inventory/badges/RequestBadgesComposer.ts new file mode 100644 index 00000000..8dc95eb3 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/inventory/badges/RequestBadgesComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class RequestBadgesComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/outgoing/inventory/badges/SetActivatedBadgesComposer.ts b/src/nitro/communication/messages/outgoing/inventory/badges/SetActivatedBadgesComposer.ts new file mode 100644 index 00000000..4524b6e3 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/inventory/badges/SetActivatedBadgesComposer.ts @@ -0,0 +1,40 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class SetActivatedBadgesComposer implements IMessageComposer +{ + private _badges: string[] = []; + + public getMessageArray() + { + const data = []; + let local2 = 1; + while(local2 <= 5) + { + if(local2 <= this._badges.length) + { + data.push(local2); + data.push(this._badges[(local2 - 1)]); + } + else + { + data.push(local2); + data.push(''); + } + + local2++; + } + return data; + } + + public dispose(): void + { + return; + } + + public addActivatedBadge(badge: string): void + { + if(this._badges.length >= 5) return; + + this._badges.push(badge); + } +} diff --git a/src/nitro/communication/messages/outgoing/inventory/bots/GetBotInventoryComposer.ts b/src/nitro/communication/messages/outgoing/inventory/bots/GetBotInventoryComposer.ts new file mode 100644 index 00000000..48a6767f --- /dev/null +++ b/src/nitro/communication/messages/outgoing/inventory/bots/GetBotInventoryComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class GetBotInventoryComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/inventory/furni/FurnitureList2Composer.ts b/src/nitro/communication/messages/outgoing/inventory/furni/FurnitureList2Composer.ts new file mode 100644 index 00000000..8d2b2290 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/inventory/furni/FurnitureList2Composer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class FurnitureList2Composer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/inventory/furni/FurnitureListComposer.ts b/src/nitro/communication/messages/outgoing/inventory/furni/FurnitureListComposer.ts new file mode 100644 index 00000000..d7e2d5e5 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/inventory/furni/FurnitureListComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class FurnitureListComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/inventory/pets/RequestPetsComposer.ts b/src/nitro/communication/messages/outgoing/inventory/pets/RequestPetsComposer.ts new file mode 100644 index 00000000..885d75bf --- /dev/null +++ b/src/nitro/communication/messages/outgoing/inventory/pets/RequestPetsComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class RequestPetsComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/outgoing/inventory/trading/TradingAcceptComposer.ts b/src/nitro/communication/messages/outgoing/inventory/trading/TradingAcceptComposer.ts new file mode 100644 index 00000000..0dfbe6b5 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/inventory/trading/TradingAcceptComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class TradingAcceptComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/inventory/trading/TradingCancelComposer.ts b/src/nitro/communication/messages/outgoing/inventory/trading/TradingCancelComposer.ts new file mode 100644 index 00000000..d7382448 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/inventory/trading/TradingCancelComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class TradingCancelComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/inventory/trading/TradingCloseComposer.ts b/src/nitro/communication/messages/outgoing/inventory/trading/TradingCloseComposer.ts new file mode 100644 index 00000000..519c6632 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/inventory/trading/TradingCloseComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class TradingCloseComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/inventory/trading/TradingConfirmationComposer.ts b/src/nitro/communication/messages/outgoing/inventory/trading/TradingConfirmationComposer.ts new file mode 100644 index 00000000..d6152aa3 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/inventory/trading/TradingConfirmationComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class TradingConfirmationComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/inventory/trading/TradingListAddItemComposer.ts b/src/nitro/communication/messages/outgoing/inventory/trading/TradingListAddItemComposer.ts new file mode 100644 index 00000000..cf6bdccf --- /dev/null +++ b/src/nitro/communication/messages/outgoing/inventory/trading/TradingListAddItemComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class TradingListAddItemComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(itemId: number) + { + this._data = [ itemId ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/inventory/trading/TradingListAddItemsComposer.ts b/src/nitro/communication/messages/outgoing/inventory/trading/TradingListAddItemsComposer.ts new file mode 100644 index 00000000..575a30e1 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/inventory/trading/TradingListAddItemsComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class TradingListAddItemsComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(...itemIds: number[]) + { + this._data = [ itemIds.length, ...itemIds ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/inventory/trading/TradingListRemoveItemComposer.ts b/src/nitro/communication/messages/outgoing/inventory/trading/TradingListRemoveItemComposer.ts new file mode 100644 index 00000000..148109d9 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/inventory/trading/TradingListRemoveItemComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class TradingListItemRemoveComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(itemId: number) + { + this._data = [ itemId ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/inventory/trading/TradingOpenComposer.ts b/src/nitro/communication/messages/outgoing/inventory/trading/TradingOpenComposer.ts new file mode 100644 index 00000000..406c3b9e --- /dev/null +++ b/src/nitro/communication/messages/outgoing/inventory/trading/TradingOpenComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class TradingOpenComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(userId: number) + { + this._data = [ userId ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/inventory/trading/TradingUnacceptComposer.ts b/src/nitro/communication/messages/outgoing/inventory/trading/TradingUnacceptComposer.ts new file mode 100644 index 00000000..7f02bf22 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/inventory/trading/TradingUnacceptComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class TradingUnacceptComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/modtool/ModtoolChangeRoomSettingsComposer.ts b/src/nitro/communication/messages/outgoing/modtool/ModtoolChangeRoomSettingsComposer.ts new file mode 100644 index 00000000..168ff4eb --- /dev/null +++ b/src/nitro/communication/messages/outgoing/modtool/ModtoolChangeRoomSettingsComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class ModtoolChangeRoomSettingsComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(roomId: number, lockDoor: number, changeTitle: number, kickUsers: number) + { + this._data = [ roomId, lockDoor, changeTitle, kickUsers ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/outgoing/modtool/ModtoolEventAlertComposer.ts b/src/nitro/communication/messages/outgoing/modtool/ModtoolEventAlertComposer.ts new file mode 100644 index 00000000..59d71974 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/modtool/ModtoolEventAlertComposer.ts @@ -0,0 +1,27 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class ModtoolEventAlertComposer implements IMessageComposer +{ + private _data: any[] = []; + + constructor(k: number, arg2: string, arg3: number, arg4: number = -1) + { + this._data.push(k); + this._data.push(arg2); + this._data.push(arg3); + if(arg4 != -1) + { + this._data.push(arg4); + } + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/outgoing/modtool/ModtoolRequestRoomChatlogComposer.ts b/src/nitro/communication/messages/outgoing/modtool/ModtoolRequestRoomChatlogComposer.ts new file mode 100644 index 00000000..3a87a54e --- /dev/null +++ b/src/nitro/communication/messages/outgoing/modtool/ModtoolRequestRoomChatlogComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class ModtoolRequestRoomChatlogComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(roomId: number, useless: number = 0) + { + this._data = [ useless, roomId ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/outgoing/modtool/ModtoolRequestRoomInfoComposer.ts b/src/nitro/communication/messages/outgoing/modtool/ModtoolRequestRoomInfoComposer.ts new file mode 100644 index 00000000..1dbd40d0 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/modtool/ModtoolRequestRoomInfoComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class ModtoolRequestRoomInfoComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(roomId: number) + { + this._data = [ roomId ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/outgoing/modtool/ModtoolRequestUserChatlogComposer.ts b/src/nitro/communication/messages/outgoing/modtool/ModtoolRequestUserChatlogComposer.ts new file mode 100644 index 00000000..b1634684 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/modtool/ModtoolRequestUserChatlogComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class ModtoolRequestUserChatlogComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(userId: number) + { + this._data = [ userId ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/outgoing/modtool/ModtoolRequestUserInfoComposer.ts b/src/nitro/communication/messages/outgoing/modtool/ModtoolRequestUserInfoComposer.ts new file mode 100644 index 00000000..c29f16fb --- /dev/null +++ b/src/nitro/communication/messages/outgoing/modtool/ModtoolRequestUserInfoComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class ModtoolRequestUserInfoComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(userId: number) + { + this._data = [ userId ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/outgoing/modtool/ModtoolRequestUserRoomsComposer.ts b/src/nitro/communication/messages/outgoing/modtool/ModtoolRequestUserRoomsComposer.ts new file mode 100644 index 00000000..ed99c4cc --- /dev/null +++ b/src/nitro/communication/messages/outgoing/modtool/ModtoolRequestUserRoomsComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class ModtoolRequestUserRoomsComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number) + { + this._data = [ k ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/outgoing/modtool/ModtoolRoomAlertComposer.ts b/src/nitro/communication/messages/outgoing/modtool/ModtoolRoomAlertComposer.ts new file mode 100644 index 00000000..0870af32 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/modtool/ModtoolRoomAlertComposer.ts @@ -0,0 +1,23 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class ModtoolRoomAlertComposer implements IMessageComposer +{ + private _data: any[] = []; + + constructor(k: number, arg2: string, arg3: string) + { + this._data.push(k); + this._data.push(arg2); + this._data.push(arg3); + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/outgoing/modtool/ModtoolSanctionAlertComposer.ts b/src/nitro/communication/messages/outgoing/modtool/ModtoolSanctionAlertComposer.ts new file mode 100644 index 00000000..0bb5ee24 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/modtool/ModtoolSanctionAlertComposer.ts @@ -0,0 +1,27 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class ModtoolSanctionAlertComposer implements IMessageComposer +{ + private _data: any[] = []; + + constructor(k: number, arg2: string, arg3: number, arg4: number = -1) + { + this._data.push(k); + this._data.push(arg2); + this._data.push(arg3); + if(arg4 != -1) + { + this._data.push(arg4); + } + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/outgoing/modtool/ModtoolSanctionBanComposer.ts b/src/nitro/communication/messages/outgoing/modtool/ModtoolSanctionBanComposer.ts new file mode 100644 index 00000000..f1a47fa9 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/modtool/ModtoolSanctionBanComposer.ts @@ -0,0 +1,29 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class ModtoolSanctionBanComposer implements IMessageComposer +{ + private _data: any[] = []; + + constructor(k: number, arg2: string, arg3: number, arg4:number, arg5: boolean, arg6: number = -1) + { + this._data.push(k); + this._data.push(arg2); + this._data.push(arg3); + this._data.push(arg4); + this._data.push(arg5); + if(arg6 != -1) + { + this._data.push(arg6); + } + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/outgoing/modtool/ModtoolSanctionKickComposer.ts b/src/nitro/communication/messages/outgoing/modtool/ModtoolSanctionKickComposer.ts new file mode 100644 index 00000000..1b5bd86d --- /dev/null +++ b/src/nitro/communication/messages/outgoing/modtool/ModtoolSanctionKickComposer.ts @@ -0,0 +1,27 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class ModtoolSanctionKickComposer implements IMessageComposer +{ + private _data: any[] = []; + + constructor(k: number, arg2: string, arg3: number, arg4: number = -1) + { + this._data.push(k); + this._data.push(arg2); + this._data.push(arg3); + if(arg4 != -1) + { + this._data.push(arg4); + } + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/outgoing/modtool/ModtoolSanctionMuteComposer.ts b/src/nitro/communication/messages/outgoing/modtool/ModtoolSanctionMuteComposer.ts new file mode 100644 index 00000000..b6a67e69 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/modtool/ModtoolSanctionMuteComposer.ts @@ -0,0 +1,27 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class ModtoolSanctionMuteComposer implements IMessageComposer +{ + private _data: any[] = []; + + constructor(k: number, arg2: string, arg3: number, arg4: number = -1) + { + this._data.push(k); + this._data.push(arg2); + this._data.push(arg3); + if(arg4 != -1) + { + this._data.push(arg4); + } + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/outgoing/modtool/ModtoolSanctionTradelockComposer.ts b/src/nitro/communication/messages/outgoing/modtool/ModtoolSanctionTradelockComposer.ts new file mode 100644 index 00000000..bf7c0616 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/modtool/ModtoolSanctionTradelockComposer.ts @@ -0,0 +1,28 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class ModtoolSanctionTradelockComposer implements IMessageComposer +{ + private _data: any[] = []; + + constructor(k: number, arg2: string, arg3: number, arg4: number, arg5: number = -1) + { + this._data.push(k); + this._data.push(arg2); + this._data.push(arg3); + this._data.push(arg4); + if(arg5 != -1) + { + this._data.push(arg5); + } + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/outgoing/navigator/ConvertGlobalRoomIdComposer.ts b/src/nitro/communication/messages/outgoing/navigator/ConvertGlobalRoomIdComposer.ts new file mode 100644 index 00000000..7b450688 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/navigator/ConvertGlobalRoomIdComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class ConvertGlobalRoomIdMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(flatId: string) + { + this._data = [ flatId ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/navigator/NavigatorCategoriesComposer.ts b/src/nitro/communication/messages/outgoing/navigator/NavigatorCategoriesComposer.ts new file mode 100644 index 00000000..0b343158 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/navigator/NavigatorCategoriesComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class NavigatorCategoriesComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/navigator/NavigatorCategoryListModeComposer.ts b/src/nitro/communication/messages/outgoing/navigator/NavigatorCategoryListModeComposer.ts new file mode 100644 index 00000000..297d199b --- /dev/null +++ b/src/nitro/communication/messages/outgoing/navigator/NavigatorCategoryListModeComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class NavigatorCategoryListModeComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(category: string, listmode: number) + { + this._data = [category, listmode]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/navigator/NavigatorInitComposer.ts b/src/nitro/communication/messages/outgoing/navigator/NavigatorInitComposer.ts new file mode 100644 index 00000000..7eb2a36c --- /dev/null +++ b/src/nitro/communication/messages/outgoing/navigator/NavigatorInitComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class NavigatorInitComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/navigator/NavigatorSearchCloseComposer.ts b/src/nitro/communication/messages/outgoing/navigator/NavigatorSearchCloseComposer.ts new file mode 100644 index 00000000..cb4c8fc2 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/navigator/NavigatorSearchCloseComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class NavigatorSearchCloseComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(code: string) + { + this._data = [ code ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/navigator/NavigatorSearchComposer.ts b/src/nitro/communication/messages/outgoing/navigator/NavigatorSearchComposer.ts new file mode 100644 index 00000000..edf8f2dd --- /dev/null +++ b/src/nitro/communication/messages/outgoing/navigator/NavigatorSearchComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class NavigatorSearchComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(code: string, data: string) + { + this._data = [ code, data ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/navigator/NavigatorSearchOpenComposer.ts b/src/nitro/communication/messages/outgoing/navigator/NavigatorSearchOpenComposer.ts new file mode 100644 index 00000000..aa64ac40 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/navigator/NavigatorSearchOpenComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class NavigatorSearchOpenComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(code: string) + { + this._data = [ code ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/navigator/NavigatorSearchSaveComposer.ts b/src/nitro/communication/messages/outgoing/navigator/NavigatorSearchSaveComposer.ts new file mode 100644 index 00000000..6f8af2fc --- /dev/null +++ b/src/nitro/communication/messages/outgoing/navigator/NavigatorSearchSaveComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class NavigatorSearchSaveComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(code: string, data: string) + { + this._data = [ code, data ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/navigator/NavigatorSettingsComposer.ts b/src/nitro/communication/messages/outgoing/navigator/NavigatorSettingsComposer.ts new file mode 100644 index 00000000..48c6c238 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/navigator/NavigatorSettingsComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class NavigatorSettingsComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/navigator/NavigatorSettingsSaveComposer.ts b/src/nitro/communication/messages/outgoing/navigator/NavigatorSettingsSaveComposer.ts new file mode 100644 index 00000000..4f5237f7 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/navigator/NavigatorSettingsSaveComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class NavigatorSettingsSaveComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(x: number, y: number, width: number, height: number, leftSideOpen: boolean, mode: number) + { + this._data = [ x, y, width, height, leftSideOpen, mode ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/pet/PetRespectComposer.ts b/src/nitro/communication/messages/outgoing/pet/PetRespectComposer.ts new file mode 100644 index 00000000..1276c2cb --- /dev/null +++ b/src/nitro/communication/messages/outgoing/pet/PetRespectComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class PetRespectComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(petId: number) + { + this._data = [ petId ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/pet/RequestPetInfoComposer.ts b/src/nitro/communication/messages/outgoing/pet/RequestPetInfoComposer.ts new file mode 100644 index 00000000..9aa806d8 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/pet/RequestPetInfoComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class RequestPetInfoComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(petId: number) + { + this._data = [ petId ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/outgoing/room/RoomCreateComposer.ts b/src/nitro/communication/messages/outgoing/room/RoomCreateComposer.ts new file mode 100644 index 00000000..d7c72bc4 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/RoomCreateComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class RoomCreateComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(roomName: string, roomDesc: string, modelName: string, categoryId: number, maxVisitors: number, tradeType: number) + { + this._data = [ roomName, roomDesc, modelName, categoryId, maxVisitors, tradeType ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/room/access/RoomDoorbellAccessComposer.ts b/src/nitro/communication/messages/outgoing/room/access/RoomDoorbellAccessComposer.ts new file mode 100644 index 00000000..c75da08f --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/access/RoomDoorbellAccessComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class RoomDoorbellAccessComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(user:string, allowedEntry: boolean) + { + this._data = [ user, allowedEntry ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/outgoing/room/access/RoomEnterComposer.ts b/src/nitro/communication/messages/outgoing/room/access/RoomEnterComposer.ts new file mode 100644 index 00000000..8af9aac1 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/access/RoomEnterComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class RoomEnterComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(roomId: number, password: string = null) + { + this._data = [ roomId, password ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/room/action/RoomAmbassadorAlertComposer.ts b/src/nitro/communication/messages/outgoing/room/action/RoomAmbassadorAlertComposer.ts new file mode 100644 index 00000000..2857bba6 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/action/RoomAmbassadorAlertComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class RoomAmbassadorAlertComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(userId: number) + { + this._data = [ userId ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/room/action/RoomBanUserComposer.ts b/src/nitro/communication/messages/outgoing/room/action/RoomBanUserComposer.ts new file mode 100644 index 00000000..ffad9037 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/action/RoomBanUserComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class RoomBanUserComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(userId: number, roomId: number = 0, type: string) + { + this._data = [ userId, roomId, type ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/room/action/RoomDeleteComposer.ts b/src/nitro/communication/messages/outgoing/room/action/RoomDeleteComposer.ts new file mode 100644 index 00000000..ccace071 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/action/RoomDeleteComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class RoomDeleteComposer implements IMessageComposer<[ number ]> +{ + private _data: [ number ]; + + constructor(roomId: number) + { + this._data = [ roomId ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/room/action/RoomGiveRightsComposer.ts b/src/nitro/communication/messages/outgoing/room/action/RoomGiveRightsComposer.ts new file mode 100644 index 00000000..64a765bc --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/action/RoomGiveRightsComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class RoomGiveRightsComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(userId: number) + { + this._data = [ userId ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/room/action/RoomKickUserComposer.ts b/src/nitro/communication/messages/outgoing/room/action/RoomKickUserComposer.ts new file mode 100644 index 00000000..bb3fe933 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/action/RoomKickUserComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class RoomKickUserComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(userId: number) + { + this._data = [ userId ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/room/action/RoomLikeRoomComposer.ts b/src/nitro/communication/messages/outgoing/room/action/RoomLikeRoomComposer.ts new file mode 100644 index 00000000..19824d31 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/action/RoomLikeRoomComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class RoomLikeRoomComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number) + { + this._data = [ k ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/outgoing/room/action/RoomMuteUserComposer.ts b/src/nitro/communication/messages/outgoing/room/action/RoomMuteUserComposer.ts new file mode 100644 index 00000000..a926b570 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/action/RoomMuteUserComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class RoomMuteUserComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(userId: number, minutes: number, roomId: number = 0) + { + this._data = [ userId, minutes, roomId ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/room/action/RoomStaffPickComposer.ts b/src/nitro/communication/messages/outgoing/room/action/RoomStaffPickComposer.ts new file mode 100644 index 00000000..d0ca63eb --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/action/RoomStaffPickComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class RoomStaffPickComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(roomId: number) + { + this._data = [ roomId ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/room/action/RoomTakeRightsComposer.ts b/src/nitro/communication/messages/outgoing/room/action/RoomTakeRightsComposer.ts new file mode 100644 index 00000000..3acbcf80 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/action/RoomTakeRightsComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class RoomTakeRightsComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(...userIds: number[]) + { + this._data = [ userIds.length, ...userIds ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/room/action/RoomUnbanUserComposer.ts b/src/nitro/communication/messages/outgoing/room/action/RoomUnbanUserComposer.ts new file mode 100644 index 00000000..b2bbe289 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/action/RoomUnbanUserComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class RoomUnbanUserComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(userId: number, roomId: number) + { + this._data = [ userId, roomId ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/room/bots/RequestBotConfigurationComposer.ts b/src/nitro/communication/messages/outgoing/room/bots/RequestBotConfigurationComposer.ts new file mode 100644 index 00000000..57469ac2 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/bots/RequestBotConfigurationComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class RequestBotCommandConfigurationComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(botId: number, skillId: number) + { + this._data = [ botId, skillId ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/outgoing/room/data/RoomBannedUsersComposer.ts b/src/nitro/communication/messages/outgoing/room/data/RoomBannedUsersComposer.ts new file mode 100644 index 00000000..1a6e3d55 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/data/RoomBannedUsersComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class RoomBannedUsersComposer implements IMessageComposer<[ number ]> +{ + private _data: [ number ]; + + constructor(roomId: number) + { + this._data = [ roomId ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/room/data/RoomInfoComposer.ts b/src/nitro/communication/messages/outgoing/room/data/RoomInfoComposer.ts new file mode 100644 index 00000000..8cc41a64 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/data/RoomInfoComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class RoomInfoComposer implements IMessageComposer<[ number, number, number ]> +{ + private _data: [ number, number, number ]; + + constructor(roomId: number, enterRoom: boolean, forwardRoom: boolean) + { + this._data = [ roomId, (enterRoom ? 1 : 0), (forwardRoom ? 1 : 0) ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/room/data/RoomSettingsComposer.ts b/src/nitro/communication/messages/outgoing/room/data/RoomSettingsComposer.ts new file mode 100644 index 00000000..8a5b9bd2 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/data/RoomSettingsComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class RoomSettingsComposer implements IMessageComposer<[ number ]> +{ + private _data: [ number ]; + + constructor(roomId: number) + { + this._data = [ roomId ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/room/data/RoomUsersWithRightsComposer.ts b/src/nitro/communication/messages/outgoing/room/data/RoomUsersWithRightsComposer.ts new file mode 100644 index 00000000..534ee327 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/data/RoomUsersWithRightsComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class RoomUsersWithRightsComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(roomId: number) + { + this._data = [ roomId ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/outgoing/room/data/SaveRoomSettingsComposer.ts b/src/nitro/communication/messages/outgoing/room/data/SaveRoomSettingsComposer.ts new file mode 100644 index 00000000..72b45056 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/data/SaveRoomSettingsComposer.ts @@ -0,0 +1,70 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class SaveRoomSettingsComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(roomId: number, + roomName: string, + roomDescription: string, + lockState: number, + password: string, + userCount: number, + categoryId: number, + tagsCount: number, + tags: string[], + tradeState: number, + allowPets: boolean, + allowPetsEat: boolean, + allowWalkthrough: boolean, + hideWalls: boolean, + wallThickness: number, + floorThickness: number, + muteState: number, + kickState: number, + banState: number, + chatBubbleMode: number, + chatBubbleWeight: number, + chatBubbleSpeed: number, + chatDistance: number, + chatFloodProtection: number + ) + { + this._data = [ + roomId, + roomName, + roomDescription, + lockState, + password, + userCount, + categoryId, + tagsCount, + tags, + tradeState, + allowPets, + allowPetsEat, + allowWalkthrough, + hideWalls, + wallThickness, + floorThickness, + muteState, + kickState, + banState, + chatBubbleMode, + chatBubbleWeight, + chatBubbleSpeed, + chatDistance, + chatFloodProtection + ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/room/engine/BotPlaceComposer.ts b/src/nitro/communication/messages/outgoing/room/engine/BotPlaceComposer.ts new file mode 100644 index 00000000..c10831bb --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/engine/BotPlaceComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class BotPlaceComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(botId: number, x: number, y: number) + { + this._data = [ botId, x, y ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/outgoing/room/engine/BotRemoveComposer.ts b/src/nitro/communication/messages/outgoing/room/engine/BotRemoveComposer.ts new file mode 100644 index 00000000..8acbfbe5 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/engine/BotRemoveComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class BotRemoveComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(botId: number) + { + this._data = [ botId ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/outgoing/room/engine/BotSkillSaveComposer.ts b/src/nitro/communication/messages/outgoing/room/engine/BotSkillSaveComposer.ts new file mode 100644 index 00000000..2a1950ff --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/engine/BotSkillSaveComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class BotSkillSaveComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(botId: number, skill: number, data: string) + { + this._data = [ botId, skill, data ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/outgoing/room/engine/GetItemDataComposer.ts b/src/nitro/communication/messages/outgoing/room/engine/GetItemDataComposer.ts new file mode 100644 index 00000000..1d3c3ff6 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/engine/GetItemDataComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class GetItemDataComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(itemId: number) + { + this._data = [ itemId ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/room/engine/ModifyWallItemDataComposer.ts b/src/nitro/communication/messages/outgoing/room/engine/ModifyWallItemDataComposer.ts new file mode 100644 index 00000000..62ae8bd9 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/engine/ModifyWallItemDataComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class ModifyWallItemDataComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(itemId: number, colorHex: string, text: string) + { + this._data = [ itemId, colorHex, text ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/room/engine/PetMoveComposer.ts b/src/nitro/communication/messages/outgoing/room/engine/PetMoveComposer.ts new file mode 100644 index 00000000..224b7744 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/engine/PetMoveComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class PetMoveComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(petId: number, x: number, y: number, direction: number) + { + this._data = [ petId, x, y, direction ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/outgoing/room/engine/PetPlaceComposer.ts b/src/nitro/communication/messages/outgoing/room/engine/PetPlaceComposer.ts new file mode 100644 index 00000000..8de678f9 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/engine/PetPlaceComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class PetPlaceComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(petId: number, x: number, y: number) + { + this._data = [ petId, x, y ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/outgoing/room/engine/PetRemoveComposer.ts b/src/nitro/communication/messages/outgoing/room/engine/PetRemoveComposer.ts new file mode 100644 index 00000000..167297e4 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/engine/PetRemoveComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class PetRemoveComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(petId: number) + { + this._data = [ petId ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/outgoing/room/engine/RemoveWallItemComposer.ts b/src/nitro/communication/messages/outgoing/room/engine/RemoveWallItemComposer.ts new file mode 100644 index 00000000..92d97db6 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/engine/RemoveWallItemComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class RemoveWallItemComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(itemId: number) + { + this._data = [ itemId ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/room/furniture/FurnitureAliasesComposer.ts b/src/nitro/communication/messages/outgoing/room/furniture/FurnitureAliasesComposer.ts new file mode 100644 index 00000000..e9830306 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/furniture/FurnitureAliasesComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class FurnitureAliasesComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/room/furniture/FurniturePickupComposer.ts b/src/nitro/communication/messages/outgoing/room/furniture/FurniturePickupComposer.ts new file mode 100644 index 00000000..fe2b7851 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/furniture/FurniturePickupComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class FurniturePickupComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(category: number, objectId: number) + { + this._data = [ category, objectId ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/room/furniture/FurniturePlaceComposer.ts b/src/nitro/communication/messages/outgoing/room/furniture/FurniturePlaceComposer.ts new file mode 100644 index 00000000..69baa88b --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/furniture/FurniturePlaceComposer.ts @@ -0,0 +1,40 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; +import { RoomObjectCategory } from '../../../../../room/object/RoomObjectCategory'; + +export class FurniturePlaceComposer implements IMessageComposer +{ + private _itemId: number; + private _category: number; + private _wallLocation: string; + private _x: number; + private _y: number; + private _direction: number; + + constructor(itemId: number, category: number, wallLocation: string, x: number, y: number, direction: number) + { + this._itemId = itemId; + this._category = category; + this._wallLocation = wallLocation; + this._x = x; + this._y = y; + this._direction = direction; + } + + public getMessageArray() + { + switch(this._category) + { + case RoomObjectCategory.FLOOR: + return [ `${ this._itemId } ${ this._x } ${ this._y } ${ this._direction }` ]; + case RoomObjectCategory.WALL: + return [ `${ this._itemId } ${ this._wallLocation } ` ]; + default: + return []; + } + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/room/furniture/FurniturePlacePaintComposer.ts b/src/nitro/communication/messages/outgoing/room/furniture/FurniturePlacePaintComposer.ts new file mode 100644 index 00000000..81cfd23f --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/furniture/FurniturePlacePaintComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class FurniturePlacePaintComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(furniId: number) + { + this._data = [ furniId ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/room/furniture/FurniturePostItPlaceComposer.ts b/src/nitro/communication/messages/outgoing/room/furniture/FurniturePostItPlaceComposer.ts new file mode 100644 index 00000000..d6f00264 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/furniture/FurniturePostItPlaceComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class FurniturePostItPlaceComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(itemId: number, wallLocation: string) + { + this._data = [ itemId, wallLocation ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/room/furniture/ads/RoomAdsUpdateComposer.ts b/src/nitro/communication/messages/outgoing/room/furniture/ads/RoomAdsUpdateComposer.ts new file mode 100644 index 00000000..bb5df433 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/furniture/ads/RoomAdsUpdateComposer.ts @@ -0,0 +1,23 @@ +import { IMessageComposer } from '../../../../../../../core/communication/messages/IMessageComposer'; + +export class RoomAdsUpdateComposer implements IMessageComposer +{ + private _data: any[]; + + constructor(k: number, _arg_2: Map) + { + this._data = [ k, (_arg_2.size * 2) ]; + + for(const [ key, value ] of _arg_2.entries()) this._data.push( key, value ); + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/outgoing/room/furniture/dimmer/MoodlightSettingsComposer.ts b/src/nitro/communication/messages/outgoing/room/furniture/dimmer/MoodlightSettingsComposer.ts new file mode 100644 index 00000000..4ebf3ba9 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/furniture/dimmer/MoodlightSettingsComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../../core/communication/messages/IMessageComposer'; + +export class MoodlightSettingsComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/outgoing/room/furniture/dimmer/MoodlightSettingsSaveComposer.ts b/src/nitro/communication/messages/outgoing/room/furniture/dimmer/MoodlightSettingsSaveComposer.ts new file mode 100644 index 00000000..75d58b1a --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/furniture/dimmer/MoodlightSettingsSaveComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../../core/communication/messages/IMessageComposer'; + +export class MoodlightSettingsSaveComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number, arg2: number, arg3: string, arg4:number, arg5:boolean) + { + this._data = [k, arg2, arg3, arg4, arg5]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/outgoing/room/furniture/dimmer/MoodlightTogggleStateComposer.ts b/src/nitro/communication/messages/outgoing/room/furniture/dimmer/MoodlightTogggleStateComposer.ts new file mode 100644 index 00000000..908f2086 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/furniture/dimmer/MoodlightTogggleStateComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../../core/communication/messages/IMessageComposer'; + +export class MoodlightTogggleStateComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/outgoing/room/furniture/floor/FurnitureFloorUpdateComposer.ts b/src/nitro/communication/messages/outgoing/room/furniture/floor/FurnitureFloorUpdateComposer.ts new file mode 100644 index 00000000..e5ca5b83 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/furniture/floor/FurnitureFloorUpdateComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../../core/communication/messages/IMessageComposer'; + +export class FurnitureFloorUpdateComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(itemId: number, x: number, y: number, direction: number) + { + this._data = [ itemId, x, y, direction ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/room/furniture/logic/FurnitureColorWheelComposer.ts b/src/nitro/communication/messages/outgoing/room/furniture/logic/FurnitureColorWheelComposer.ts new file mode 100644 index 00000000..c08d5a10 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/furniture/logic/FurnitureColorWheelComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../../core/communication/messages/IMessageComposer'; + +export class FurnitureColorWheelComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(itemId: number) + { + this._data = [ itemId ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/room/furniture/logic/FurnitureDiceActivateComposer.ts b/src/nitro/communication/messages/outgoing/room/furniture/logic/FurnitureDiceActivateComposer.ts new file mode 100644 index 00000000..1a8c1b06 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/furniture/logic/FurnitureDiceActivateComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../../core/communication/messages/IMessageComposer'; + +export class FurnitureDiceActivateComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(itemId: number) + { + this._data = [ itemId ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/room/furniture/logic/FurnitureDiceDeactivateComposer.ts b/src/nitro/communication/messages/outgoing/room/furniture/logic/FurnitureDiceDeactivateComposer.ts new file mode 100644 index 00000000..26df9419 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/furniture/logic/FurnitureDiceDeactivateComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../../core/communication/messages/IMessageComposer'; + +export class FurnitureDiceDeactivateComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(itemId: number) + { + this._data = [ itemId ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/room/furniture/logic/FurnitureExchangeComposer.ts b/src/nitro/communication/messages/outgoing/room/furniture/logic/FurnitureExchangeComposer.ts new file mode 100644 index 00000000..64ea9146 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/furniture/logic/FurnitureExchangeComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../../core/communication/messages/IMessageComposer'; + +export class FurnitureExchangeComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(itemId: number) + { + this._data = [ itemId ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/room/furniture/logic/FurnitureMultiStateComposer.ts b/src/nitro/communication/messages/outgoing/room/furniture/logic/FurnitureMultiStateComposer.ts new file mode 100644 index 00000000..bc738176 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/furniture/logic/FurnitureMultiStateComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../../core/communication/messages/IMessageComposer'; + +export class FurnitureMultiStateComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(itemId: number, state: number = 0) + { + this._data = [ itemId, state ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/outgoing/room/furniture/logic/FurnitureOneWayDoorComposer.ts b/src/nitro/communication/messages/outgoing/room/furniture/logic/FurnitureOneWayDoorComposer.ts new file mode 100644 index 00000000..e984b05e --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/furniture/logic/FurnitureOneWayDoorComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../../core/communication/messages/IMessageComposer'; + +export class FurnitureOneWayDoorComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(itemId: number) + { + this._data = [ itemId ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/room/furniture/logic/FurnitureRandomStateComposer.ts b/src/nitro/communication/messages/outgoing/room/furniture/logic/FurnitureRandomStateComposer.ts new file mode 100644 index 00000000..0aec328f --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/furniture/logic/FurnitureRandomStateComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../../core/communication/messages/IMessageComposer'; + +export class FurnitureRandomStateComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(itemId: number, state: number) + { + this._data = [ itemId, state ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/room/furniture/logic/FurnitureStackHeightComposer.ts b/src/nitro/communication/messages/outgoing/room/furniture/logic/FurnitureStackHeightComposer.ts new file mode 100644 index 00000000..373d6ea3 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/furniture/logic/FurnitureStackHeightComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../../core/communication/messages/IMessageComposer'; + +export class FurnitureStackHeightComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(itemId: number, height: number = -100) + { + this._data = [ itemId, height ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/room/furniture/logic/FurnitureWallMultiStateComposer.ts b/src/nitro/communication/messages/outgoing/room/furniture/logic/FurnitureWallMultiStateComposer.ts new file mode 100644 index 00000000..6af2ac17 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/furniture/logic/FurnitureWallMultiStateComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../../core/communication/messages/IMessageComposer'; + +export class FurnitureWallMultiStateComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(itemId: number, state: number) + { + this._data = [ itemId, state ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/room/furniture/logic/LoveLockStartConfirmComposer.ts b/src/nitro/communication/messages/outgoing/room/furniture/logic/LoveLockStartConfirmComposer.ts new file mode 100644 index 00000000..7f9d0b8e --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/furniture/logic/LoveLockStartConfirmComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../../core/communication/messages/IMessageComposer'; + +export class LoveLockStartConfirmComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(itemId: number, confirmed: boolean) + { + this._data = [ itemId, confirmed ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/outgoing/room/furniture/mannequin/FurnitureMannequinSaveLookComposer.ts b/src/nitro/communication/messages/outgoing/room/furniture/mannequin/FurnitureMannequinSaveLookComposer.ts new file mode 100644 index 00000000..9167af1d --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/furniture/mannequin/FurnitureMannequinSaveLookComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../../core/communication/messages/IMessageComposer'; + +export class FurnitureMannequinSaveLookComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number) + { + this._data = [ k ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/outgoing/room/furniture/mannequin/FurnitureMannequinSaveNameComposer.ts b/src/nitro/communication/messages/outgoing/room/furniture/mannequin/FurnitureMannequinSaveNameComposer.ts new file mode 100644 index 00000000..7665d720 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/furniture/mannequin/FurnitureMannequinSaveNameComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../../core/communication/messages/IMessageComposer'; + +export class FurnitureMannequinSaveNameComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(itemId: number, name: string) + { + this._data = [ itemId, name ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/outgoing/room/furniture/presents/OpenPresentComposer.ts b/src/nitro/communication/messages/outgoing/room/furniture/presents/OpenPresentComposer.ts new file mode 100644 index 00000000..be8aebb0 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/furniture/presents/OpenPresentComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../../core/communication/messages/IMessageComposer'; + +export class OpenPresentComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number) + { + this._data = [k]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/outgoing/room/furniture/toner/ApplyTonerComposer.ts b/src/nitro/communication/messages/outgoing/room/furniture/toner/ApplyTonerComposer.ts new file mode 100644 index 00000000..4a122db3 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/furniture/toner/ApplyTonerComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../../core/communication/messages/IMessageComposer'; + +export class ApplyTonerComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(k: number, arg2:number, arg3: number, arg4: number) + { + this._data = [k, arg2, arg3, arg4]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/outgoing/room/furniture/wall/FurnitureWallUpdateComposer.ts b/src/nitro/communication/messages/outgoing/room/furniture/wall/FurnitureWallUpdateComposer.ts new file mode 100644 index 00000000..5e3a91d5 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/furniture/wall/FurnitureWallUpdateComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../../core/communication/messages/IMessageComposer'; + +export class FurnitureWallUpdateComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(itemId: number, location: string) + { + this._data = [ itemId, location ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/room/mapping/RoomModelComposer.ts b/src/nitro/communication/messages/outgoing/room/mapping/RoomModelComposer.ts new file mode 100644 index 00000000..df3c5198 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/mapping/RoomModelComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class RoomModelComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/room/unit/RoomUnitActionComposer.ts b/src/nitro/communication/messages/outgoing/room/unit/RoomUnitActionComposer.ts new file mode 100644 index 00000000..8028cae8 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/unit/RoomUnitActionComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class RoomUnitActionComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(actionType: number) + { + this._data = [ actionType ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/room/unit/RoomUnitDanceComposer.ts b/src/nitro/communication/messages/outgoing/room/unit/RoomUnitDanceComposer.ts new file mode 100644 index 00000000..58c57443 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/unit/RoomUnitDanceComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class RoomUnitDanceComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(danceType: number) + { + this._data = [ danceType ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/room/unit/RoomUnitDropHandItemComposer.ts b/src/nitro/communication/messages/outgoing/room/unit/RoomUnitDropHandItemComposer.ts new file mode 100644 index 00000000..abda3bc4 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/unit/RoomUnitDropHandItemComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class RoomUnitDropHandItemComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = [ ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/room/unit/RoomUnitGiveHandItemComposer.ts b/src/nitro/communication/messages/outgoing/room/unit/RoomUnitGiveHandItemComposer.ts new file mode 100644 index 00000000..e3092c31 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/unit/RoomUnitGiveHandItemComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class RoomUnitGiveHandItemComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(unitId: number) + { + this._data = [ unitId ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/room/unit/RoomUnitLookComposer.ts b/src/nitro/communication/messages/outgoing/room/unit/RoomUnitLookComposer.ts new file mode 100644 index 00000000..99fe6efe --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/unit/RoomUnitLookComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class RoomUnitLookComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(x: number, y: number) + { + this._data = [ x, y ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/room/unit/RoomUnitPostureComposer.ts b/src/nitro/communication/messages/outgoing/room/unit/RoomUnitPostureComposer.ts new file mode 100644 index 00000000..70d114ae --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/unit/RoomUnitPostureComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class RoomUnitPostureComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(posture: number) + { + this._data = [ posture ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/room/unit/RoomUnitSignComposer.ts b/src/nitro/communication/messages/outgoing/room/unit/RoomUnitSignComposer.ts new file mode 100644 index 00000000..fbce0153 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/unit/RoomUnitSignComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class RoomUnitSignComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(signType: number) + { + this._data = [ signType ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/room/unit/RoomUnitWalkComposer.ts b/src/nitro/communication/messages/outgoing/room/unit/RoomUnitWalkComposer.ts new file mode 100644 index 00000000..834a7379 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/unit/RoomUnitWalkComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class RoomUnitWalkComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(x: number, y: number) + { + this._data = [ x, y ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/room/unit/chat/RoomUnitChatComposer.ts b/src/nitro/communication/messages/outgoing/room/unit/chat/RoomUnitChatComposer.ts new file mode 100644 index 00000000..d2feb483 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/unit/chat/RoomUnitChatComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../../core/communication/messages/IMessageComposer'; + +export class RoomUnitChatComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(message: string, styleId: number = 0) + { + this._data = [ message, styleId ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/room/unit/chat/RoomUnitChatShoutComposer.ts b/src/nitro/communication/messages/outgoing/room/unit/chat/RoomUnitChatShoutComposer.ts new file mode 100644 index 00000000..8ac764f6 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/unit/chat/RoomUnitChatShoutComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../../core/communication/messages/IMessageComposer'; + +export class RoomUnitChatShoutComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(message: string, styleId: number) + { + this._data = [ message, styleId ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/room/unit/chat/RoomUnitChatStyleComposer.ts b/src/nitro/communication/messages/outgoing/room/unit/chat/RoomUnitChatStyleComposer.ts new file mode 100644 index 00000000..d0532d30 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/unit/chat/RoomUnitChatStyleComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../../core/communication/messages/IMessageComposer'; + +export class RoomUnitChatStyleComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(styleId: number) + { + this._data = [ styleId ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/outgoing/room/unit/chat/RoomUnitChatWhisperComposer.ts b/src/nitro/communication/messages/outgoing/room/unit/chat/RoomUnitChatWhisperComposer.ts new file mode 100644 index 00000000..e401341e --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/unit/chat/RoomUnitChatWhisperComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../../core/communication/messages/IMessageComposer'; + +export class RoomUnitChatWhisperComposer implements IMessageComposer<[ string, number ]> +{ + private _data: [ string, number ]; + + constructor(recipientName: string, message: string, styleId: number) + { + this._data = [ (recipientName + ' ' + message), styleId ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/room/unit/chat/RoomUnitTypingStartComposer.ts b/src/nitro/communication/messages/outgoing/room/unit/chat/RoomUnitTypingStartComposer.ts new file mode 100644 index 00000000..5a1fffc4 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/unit/chat/RoomUnitTypingStartComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../../core/communication/messages/IMessageComposer'; + +export class RoomUnitTypingStartComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/room/unit/chat/RoomUnitTypingStopComposer.ts b/src/nitro/communication/messages/outgoing/room/unit/chat/RoomUnitTypingStopComposer.ts new file mode 100644 index 00000000..99ada019 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/room/unit/chat/RoomUnitTypingStopComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../../core/communication/messages/IMessageComposer'; + +export class RoomUnitTypingStopComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/roomevents/ApplySnapshotMessageComposer.ts b/src/nitro/communication/messages/outgoing/roomevents/ApplySnapshotMessageComposer.ts new file mode 100644 index 00000000..3ac8e596 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/roomevents/ApplySnapshotMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class ApplySnapshotMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(id: number) + { + this._data = [ id ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/roomevents/OpenMessageComposer.ts b/src/nitro/communication/messages/outgoing/roomevents/OpenMessageComposer.ts new file mode 100644 index 00000000..bc6d30d6 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/roomevents/OpenMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class OpenMessageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(id: number) + { + this._data = [ id ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/roomevents/RoomMuteComposer.ts b/src/nitro/communication/messages/outgoing/roomevents/RoomMuteComposer.ts new file mode 100644 index 00000000..ed43c3f8 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/roomevents/RoomMuteComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class RoomMuteComposer implements IMessageComposer +{ + private _data: unknown[]; + + constructor() + { + this._data = [ ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/roomevents/UpdateActionMessageComposer.ts b/src/nitro/communication/messages/outgoing/roomevents/UpdateActionMessageComposer.ts new file mode 100644 index 00000000..ca888957 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/roomevents/UpdateActionMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class UpdateActionMessageComposer implements IMessageComposer +{ + private _data: unknown[]; + + constructor(id: number, ints: number[], string: string, stuffs: number[], delay: number, selectionCode: number) + { + this._data = [ id, ints.length, ...ints, string, stuffs.length, ...stuffs, delay, selectionCode ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/roomevents/UpdateConditionMessageComposer.ts b/src/nitro/communication/messages/outgoing/roomevents/UpdateConditionMessageComposer.ts new file mode 100644 index 00000000..c7a3c1a6 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/roomevents/UpdateConditionMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class UpdateConditionMessageComposer implements IMessageComposer +{ + private _data: unknown[]; + + constructor(id: number, ints: number[], string: string, stuffs: number[], selectionCode: number) + { + this._data = [ id, ints.length, ...ints, string, stuffs.length, ...stuffs, selectionCode ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/roomevents/UpdateTriggerMessageComposer.ts b/src/nitro/communication/messages/outgoing/roomevents/UpdateTriggerMessageComposer.ts new file mode 100644 index 00000000..e8bbb297 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/roomevents/UpdateTriggerMessageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class UpdateTriggerMessageComposer implements IMessageComposer +{ + private _data: unknown[]; + + constructor(id: number, ints: number[], string: string, stuffs: number[], selectionCode: number) + { + this._data = [ id, ints.length, ...ints, string, stuffs.length, ...stuffs, selectionCode ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/user/UserRespectComposer.ts b/src/nitro/communication/messages/outgoing/user/UserRespectComposer.ts new file mode 100644 index 00000000..e2945f61 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/user/UserRespectComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../core/communication/messages/IMessageComposer'; + +export class UserRespectComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(userId: number) + { + this._data = [ userId ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/user/data/GetIgnoredUsersComposer.ts b/src/nitro/communication/messages/outgoing/user/data/GetIgnoredUsersComposer.ts new file mode 100644 index 00000000..ce386734 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/user/data/GetIgnoredUsersComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class GetIgnoredUsersComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(username: string) + { + this._data = [ username ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/outgoing/user/data/IgnoreUserComposer.ts b/src/nitro/communication/messages/outgoing/user/data/IgnoreUserComposer.ts new file mode 100644 index 00000000..61837cbc --- /dev/null +++ b/src/nitro/communication/messages/outgoing/user/data/IgnoreUserComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class IgnoreUserComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(username: string) + { + this._data = [ username ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/outgoing/user/data/IgnoreUserIdComposer.ts b/src/nitro/communication/messages/outgoing/user/data/IgnoreUserIdComposer.ts new file mode 100644 index 00000000..a8898c83 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/user/data/IgnoreUserIdComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class IgnoreUserIdComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(userId: number) + { + this._data = [ userId ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/outgoing/user/data/UnignoreUserComposer.ts b/src/nitro/communication/messages/outgoing/user/data/UnignoreUserComposer.ts new file mode 100644 index 00000000..c6a13048 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/user/data/UnignoreUserComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class UnignoreUserComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(username: string) + { + this._data = [ username ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/outgoing/user/data/UserCurrentBadgesComposer.ts b/src/nitro/communication/messages/outgoing/user/data/UserCurrentBadgesComposer.ts new file mode 100644 index 00000000..9769d31a --- /dev/null +++ b/src/nitro/communication/messages/outgoing/user/data/UserCurrentBadgesComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class UserCurrentBadgesComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(userId: number) + { + this._data = [ userId ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/user/data/UserFigureComposer.ts b/src/nitro/communication/messages/outgoing/user/data/UserFigureComposer.ts new file mode 100644 index 00000000..0824472e --- /dev/null +++ b/src/nitro/communication/messages/outgoing/user/data/UserFigureComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class UserFigureComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(gender: string, figure: string) + { + this._data = [ gender, figure ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/user/data/UserHomeRoomComposer.ts b/src/nitro/communication/messages/outgoing/user/data/UserHomeRoomComposer.ts new file mode 100644 index 00000000..d94427e8 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/user/data/UserHomeRoomComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class UserHomeRoomComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(roomId: number) + { + this._data = [ roomId ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/user/data/UserMottoComposer.ts b/src/nitro/communication/messages/outgoing/user/data/UserMottoComposer.ts new file mode 100644 index 00000000..7b3b3c6e --- /dev/null +++ b/src/nitro/communication/messages/outgoing/user/data/UserMottoComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class UserMottoComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(motto: string) + { + this._data = [ motto ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/user/data/UserProfileComposer.ts b/src/nitro/communication/messages/outgoing/user/data/UserProfileComposer.ts new file mode 100644 index 00000000..c5538b4d --- /dev/null +++ b/src/nitro/communication/messages/outgoing/user/data/UserProfileComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class UserProfileComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(userId: number) + { + this._data = [ userId ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/user/data/UserRelationshipsComposer.ts b/src/nitro/communication/messages/outgoing/user/data/UserRelationshipsComposer.ts new file mode 100644 index 00000000..87d56b4c --- /dev/null +++ b/src/nitro/communication/messages/outgoing/user/data/UserRelationshipsComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class UserRelationshipsComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(userId: number) + { + this._data = [ userId ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/user/inventory/currency/UserCurrencyComposer.ts b/src/nitro/communication/messages/outgoing/user/inventory/currency/UserCurrencyComposer.ts new file mode 100644 index 00000000..419d2767 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/user/inventory/currency/UserCurrencyComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../../core/communication/messages/IMessageComposer'; + +export class UserCurrencyComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor() + { + this._data = []; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/user/inventory/subscription/UserSubscriptionComposer.ts b/src/nitro/communication/messages/outgoing/user/inventory/subscription/UserSubscriptionComposer.ts new file mode 100644 index 00000000..ac13dda9 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/user/inventory/subscription/UserSubscriptionComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../../core/communication/messages/IMessageComposer'; + +export class UserSubscriptionComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(type: string) + { + this._data = [ type ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/outgoing/user/settings/UserSettingsCameraFollowComposer.ts b/src/nitro/communication/messages/outgoing/user/settings/UserSettingsCameraFollowComposer.ts new file mode 100644 index 00000000..f88e8ad8 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/user/settings/UserSettingsCameraFollowComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class UserSettingsCameraFollowComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(value: boolean) + { + this._data = [ value ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/outgoing/user/settings/UserSettingsOldChatComposer.ts b/src/nitro/communication/messages/outgoing/user/settings/UserSettingsOldChatComposer.ts new file mode 100644 index 00000000..449ddddf --- /dev/null +++ b/src/nitro/communication/messages/outgoing/user/settings/UserSettingsOldChatComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class UserSettingsOldChatComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(value: boolean) + { + this._data = [ value ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/outgoing/user/settings/UserSettingsRoomInvitesComposer.ts b/src/nitro/communication/messages/outgoing/user/settings/UserSettingsRoomInvitesComposer.ts new file mode 100644 index 00000000..61e096c6 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/user/settings/UserSettingsRoomInvitesComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class UserSettingsRoomInvitesComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(value: boolean) + { + this._data = [ value ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/outgoing/user/settings/UserSettingsSoundComposer.ts b/src/nitro/communication/messages/outgoing/user/settings/UserSettingsSoundComposer.ts new file mode 100644 index 00000000..d086c507 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/user/settings/UserSettingsSoundComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class UserSettingsSoundComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(volumeSystem: number, volumeFurni: number, volumeTrax: number) + { + this._data = [ volumeSystem, volumeFurni, volumeTrax ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/outgoing/user/wardrobe/UserWardrobePageComposer.ts b/src/nitro/communication/messages/outgoing/user/wardrobe/UserWardrobePageComposer.ts new file mode 100644 index 00000000..80e35aa6 --- /dev/null +++ b/src/nitro/communication/messages/outgoing/user/wardrobe/UserWardrobePageComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class UserWardrobePageComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(pageId: number) + { + this._data = [ pageId ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/outgoing/user/wardrobe/UserWardrobeSaveComposer.ts b/src/nitro/communication/messages/outgoing/user/wardrobe/UserWardrobeSaveComposer.ts new file mode 100644 index 00000000..3a5ac70e --- /dev/null +++ b/src/nitro/communication/messages/outgoing/user/wardrobe/UserWardrobeSaveComposer.ts @@ -0,0 +1,21 @@ +import { IMessageComposer } from '../../../../../../core/communication/messages/IMessageComposer'; + +export class UserWardrobeSaveComposer implements IMessageComposer> +{ + private _data: ConstructorParameters; + + constructor(slotId: number, look: string, gender: string) + { + this._data = [ slotId, look, gender ]; + } + + public getMessageArray() + { + return this._data; + } + + public dispose(): void + { + return; + } +} diff --git a/src/nitro/communication/messages/parser/availability/AvailabilityStatusMessageParser.ts b/src/nitro/communication/messages/parser/availability/AvailabilityStatusMessageParser.ts new file mode 100644 index 00000000..4f9f47df --- /dev/null +++ b/src/nitro/communication/messages/parser/availability/AvailabilityStatusMessageParser.ts @@ -0,0 +1,48 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; + +export class AvailabilityStatusMessageParser implements IMessageParser +{ + private _isOpen: boolean; + private _onShutdown: boolean; + private _isAuthenticUser: boolean; + + public flush(): boolean + { + this._isOpen = false; + this._onShutdown = false; + this._isAuthenticUser = false; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._isOpen = wrapper.readBoolean(); + this._onShutdown = wrapper.readBoolean(); + + if(wrapper.bytesAvailable) + { + this._isAuthenticUser = wrapper.readBoolean(); + } + + return true; + } + + public get isOpen(): boolean + { + return this._isOpen; + } + + public get onShutdown(): boolean + { + return this._onShutdown; + } + + public get isAuthenticUser(): boolean + { + return this._isAuthenticUser; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/avatar/ChangeNameUpdateParser.ts b/src/nitro/communication/messages/parser/avatar/ChangeNameUpdateParser.ts new file mode 100644 index 00000000..1624c314 --- /dev/null +++ b/src/nitro/communication/messages/parser/avatar/ChangeNameUpdateParser.ts @@ -0,0 +1,52 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; + +export class ChangeNameUpdateParser implements IMessageParser +{ + private _resultCode: number; + private _name: string; + private _nameSuggestions; + + public flush(): boolean + { + this._resultCode = -1; + this._name = ''; + this._nameSuggestions = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._resultCode = wrapper.readInt(); + this._name = wrapper.readString(); + + let totalSuggestions = wrapper.readInt(); + + while(totalSuggestions > 0) + { + this._nameSuggestions.push(wrapper.readString()); + + totalSuggestions--; + } + + return true; + } + + public get resultCode(): number + { + return this._resultCode; + } + + public get name(): string + { + return this._name; + } + + public get nameSuggestions(): string[] + { + return this._nameSuggestions; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/catalog/CatalogClubGiftsParser.ts b/src/nitro/communication/messages/parser/catalog/CatalogClubGiftsParser.ts new file mode 100644 index 00000000..2e1a2b40 --- /dev/null +++ b/src/nitro/communication/messages/parser/catalog/CatalogClubGiftsParser.ts @@ -0,0 +1,84 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; +import { CatalogClubOfferData } from './utils/CatalogClubOfferData'; +import { CatalogPageOfferData } from './utils/CatalogPageOfferData'; +import { _Str_5178 } from './utils/_Str_5178'; + +export class CatalogClubGiftsParser implements IMessageParser +{ + private _daysUntilNextGift:number; + private _giftsAvailable:number; + private _offers: CatalogPageOfferData[]; + private _Str_5759:Map; + + public flush(): boolean + { + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._offers = []; + this._Str_5759 = new Map(); + this._daysUntilNextGift = wrapper.readInt(); + this._giftsAvailable = wrapper.readInt(); + + let local2 = wrapper.readInt(); + + let local3 = 0; + + while(local3 < local2) + { + this._offers.push(new CatalogPageOfferData(wrapper)); + local3++; + } + + local2 = wrapper.readInt(); + local3 = 0; + + while(local3 < local2) + { + const item = new _Str_5178(wrapper); + this._Str_5759.set(item.offerId, item); + local3++; + } + + return true; + } + + public get offers(): CatalogPageOfferData[] + { + return this._offers; + } + + public get daysUntilNextGift():number + { + return this._daysUntilNextGift; + } + + public get giftsAvailable():number + { + return this._giftsAvailable; + } + + public set giftsAvailable(gifts: number) + { + this._giftsAvailable = gifts; + } + + public getOfferExtraData(offerId: number): _Str_5178 + { + if(!offerId) return null; + + return this._Str_5759.get(offerId); + } + + + public get _Str_24398():Map + { + return this._Str_5759; + } +} diff --git a/src/nitro/communication/messages/parser/catalog/CatalogClubParser.ts b/src/nitro/communication/messages/parser/catalog/CatalogClubParser.ts new file mode 100644 index 00000000..e06c1c63 --- /dev/null +++ b/src/nitro/communication/messages/parser/catalog/CatalogClubParser.ts @@ -0,0 +1,36 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; +import { CatalogClubOfferData } from './utils/CatalogClubOfferData'; + +export class CatalogClubParser implements IMessageParser +{ + private _offers: CatalogClubOfferData[]; + + public flush(): boolean + { + this._offers = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + let totalOffers = wrapper.readInt(); + + while(totalOffers > 0) + { + this._offers.push(new CatalogClubOfferData(wrapper)); + + totalOffers--; + } + + return true; + } + + public get offers(): CatalogClubOfferData[] + { + return this._offers; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/catalog/CatalogGiftConfigurationParser.ts b/src/nitro/communication/messages/parser/catalog/CatalogGiftConfigurationParser.ts new file mode 100644 index 00000000..fbaae143 --- /dev/null +++ b/src/nitro/communication/messages/parser/catalog/CatalogGiftConfigurationParser.ts @@ -0,0 +1,109 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; +import { CatalogFrontPageItem } from './utils/CatalogFrontPageItem'; +import { CatalogLocalizationData } from './utils/CatalogLocalizationData'; +import { CatalogPageOfferData } from './utils/CatalogPageOfferData'; + +export class CatalogGiftConfigurationParser implements IMessageParser +{ + private _isEnabled: boolean = false; + private _price: number = null; + private _giftWrappers: number[] = null; + private _boxTypes: number[] = null; + private _ribbonTypes: number[] = null; + private _giftFurnis: number[] = null; + + public flush(): boolean + { + this._boxTypes = null; + this._giftFurnis = null; + this._giftWrappers = null; + this._ribbonTypes = null; + this._isEnabled = null; + this._price = null; + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + const giftWrappers = []; + const boxTypes = []; + const ribbonTypes = []; + const giftFurnis = []; + this._isEnabled = wrapper.readBoolean(); + // hotel.gifts.special.price + this._price = wrapper.readInt(); + + + let _local_3 = wrapper.readInt(); + + let i = 0; + while(i < _local_3) + { + giftWrappers.push(wrapper.readInt()); + i++; + } + + _local_3 = wrapper.readInt(); + i = 0; + while(i < _local_3) + { + boxTypes.push(wrapper.readInt()); + i++; + } + + _local_3 = wrapper.readInt(); + i = 0; + while(i < _local_3) + { + ribbonTypes.push(wrapper.readInt()); + i++; + } + + _local_3 = wrapper.readInt(); + i = 0; + while(i < _local_3) + { + giftFurnis.push(wrapper.readInt()); + i++; + } + + this._giftWrappers = giftWrappers; + this._ribbonTypes = ribbonTypes; + this._giftFurnis = giftFurnis; + this._boxTypes = boxTypes; + return true; + } + + public get giftWrappers(): number[] + { + return this._giftWrappers; + } + + public get ribbonTypes(): number[] + { + return this._ribbonTypes; + } + + public get giftFurnis(): number[] + { + return this._giftFurnis; + } + + public get boxTypes(): number[] + { + return this._boxTypes; + } + + public get isEnabled(): boolean + { + return this._isEnabled; + } + + public get price(): number + { + return this._price; + } +} diff --git a/src/nitro/communication/messages/parser/catalog/CatalogGiftUsernameUnavailableParser.ts b/src/nitro/communication/messages/parser/catalog/CatalogGiftUsernameUnavailableParser.ts new file mode 100644 index 00000000..a33a9898 --- /dev/null +++ b/src/nitro/communication/messages/parser/catalog/CatalogGiftUsernameUnavailableParser.ts @@ -0,0 +1,21 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; + +export class CatalogGiftUsernameUnavailableParser implements IMessageParser +{ + + public flush(): boolean + { + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + return true; + } + + +} diff --git a/src/nitro/communication/messages/parser/catalog/CatalogGroupsParser.ts b/src/nitro/communication/messages/parser/catalog/CatalogGroupsParser.ts new file mode 100644 index 00000000..09694dad --- /dev/null +++ b/src/nitro/communication/messages/parser/catalog/CatalogGroupsParser.ts @@ -0,0 +1,36 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; +import { CatalogGroupData } from './utils/CatalogGroupData'; + +export class CatalogGroupsParser implements IMessageParser +{ + private _groups: CatalogGroupData[]; + + public flush(): boolean + { + this._groups = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + let totalOffers = wrapper.readInt(); + + while(totalOffers > 0) + { + this._groups.push(new CatalogGroupData(wrapper)); + + totalOffers--; + } + + return true; + } + + public get groups(): CatalogGroupData[] + { + return this._groups; + } +} diff --git a/src/nitro/communication/messages/parser/catalog/CatalogModeParser.ts b/src/nitro/communication/messages/parser/catalog/CatalogModeParser.ts new file mode 100644 index 00000000..97ec9b7f --- /dev/null +++ b/src/nitro/communication/messages/parser/catalog/CatalogModeParser.ts @@ -0,0 +1,28 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; + +export class CatalogModeParser implements IMessageParser +{ + private _mode: number; + + public flush(): boolean + { + this._mode = -1; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._mode = wrapper.readInt(); + + return true; + } + + public get mode(): number + { + return this._mode; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/catalog/CatalogPageParser.ts b/src/nitro/communication/messages/parser/catalog/CatalogPageParser.ts new file mode 100644 index 00000000..021b9656 --- /dev/null +++ b/src/nitro/communication/messages/parser/catalog/CatalogPageParser.ts @@ -0,0 +1,108 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; +import { CatalogFrontPageItem } from './utils/CatalogFrontPageItem'; +import { CatalogLocalizationData } from './utils/CatalogLocalizationData'; +import { CatalogPageOfferData } from './utils/CatalogPageOfferData'; +import { ICatalogPageParser } from './utils/ICatalogPageParser'; + +export class CatalogPageParser implements IMessageParser, ICatalogPageParser +{ + private _pageId: number; + private _catalogType: string; + private _layoutCode: string; + private _localization: CatalogLocalizationData; + private _offers: CatalogPageOfferData[]; + private _offerId: number; + private _acceptSeasonCurrencyAsCredits: boolean; + private _frontPageItems: CatalogFrontPageItem[]; + + public flush(): boolean + { + this._pageId = -1; + this._catalogType = null; + this._layoutCode = null; + this._localization = null; + this._offers = []; + this._offerId = -1; + this._acceptSeasonCurrencyAsCredits = false; + this._frontPageItems = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._pageId = wrapper.readInt(); + this._catalogType = wrapper.readString(); + this._layoutCode = wrapper.readString(); + this._localization = new CatalogLocalizationData(wrapper); + + let totalOffers = wrapper.readInt(); + + while(totalOffers > 0) + { + this._offers.push(new CatalogPageOfferData(wrapper)); + + totalOffers--; + } + + this._offerId = wrapper.readInt(); + this._acceptSeasonCurrencyAsCredits = wrapper.readBoolean(); + + if(wrapper.bytesAvailable) + { + let totalFrontPageItems = wrapper.readInt(); + + while(totalFrontPageItems > 0) + { + this._frontPageItems.push(new CatalogFrontPageItem(wrapper)); + + totalFrontPageItems--; + } + } + + return true; + } + + public get pageId(): number + { + return this._pageId; + } + + public get catalogType(): string + { + return this._catalogType; + } + + public get layoutCode(): string + { + return this._layoutCode; + } + + public get localization(): CatalogLocalizationData + { + return this._localization; + } + + public get offers(): CatalogPageOfferData[] + { + return this._offers; + } + + public get offerId(): number + { + return this._offerId; + } + + public get acceptSeasonCurrencyAsCredits(): boolean + { + return this._acceptSeasonCurrencyAsCredits; + } + + public get frontPageItems(): CatalogFrontPageItem[] + { + return this._frontPageItems; + } +} diff --git a/src/nitro/communication/messages/parser/catalog/CatalogPagesParser.ts b/src/nitro/communication/messages/parser/catalog/CatalogPagesParser.ts new file mode 100644 index 00000000..099549ef --- /dev/null +++ b/src/nitro/communication/messages/parser/catalog/CatalogPagesParser.ts @@ -0,0 +1,43 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; +import { CatalogPageData } from './utils/CatalogPageData'; + +export class CatalogPagesParser implements IMessageParser +{ + private _root: CatalogPageData; + private _newAdditionsAvailable: boolean; + private _catalogType: string; + + public flush(): boolean + { + this._root = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._root = new CatalogPageData(wrapper); + this._newAdditionsAvailable = wrapper.readBoolean(); + this._catalogType = wrapper.readString(); + + return true; + } + + public get root(): CatalogPageData + { + return this._root; + } + + public get newAdditionsAvailable(): boolean + { + return this._newAdditionsAvailable; + } + + public get catalogType(): string + { + return this._catalogType; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/catalog/CatalogPurchaseFailedParser.ts b/src/nitro/communication/messages/parser/catalog/CatalogPurchaseFailedParser.ts new file mode 100644 index 00000000..e125b690 --- /dev/null +++ b/src/nitro/communication/messages/parser/catalog/CatalogPurchaseFailedParser.ts @@ -0,0 +1,28 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; + +export class CatalogPurchaseFailedParser implements IMessageParser +{ + private _code: number; + + public flush(): boolean + { + this._code = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._code = wrapper.readInt(); + + return true; + } + + public get code(): number + { + return this._code; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/catalog/CatalogPurchaseParser.ts b/src/nitro/communication/messages/parser/catalog/CatalogPurchaseParser.ts new file mode 100644 index 00000000..239d13aa --- /dev/null +++ b/src/nitro/communication/messages/parser/catalog/CatalogPurchaseParser.ts @@ -0,0 +1,29 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; +import { CatalogPurchaseData } from './utils/CatalogPurchaseData'; + +export class CatalogPurchaseParser implements IMessageParser +{ + private _offer: CatalogPurchaseData; + + public flush(): boolean + { + this._offer = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._offer = new CatalogPurchaseData(wrapper); + + return true; + } + + public get offer(): CatalogPurchaseData + { + return this._offer; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/catalog/CatalogPurchaseUnavailableParser.ts b/src/nitro/communication/messages/parser/catalog/CatalogPurchaseUnavailableParser.ts new file mode 100644 index 00000000..89707f25 --- /dev/null +++ b/src/nitro/communication/messages/parser/catalog/CatalogPurchaseUnavailableParser.ts @@ -0,0 +1,28 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; + +export class CatalogPurchaseUnavailableParser implements IMessageParser +{ + private _code: number; + + public flush(): boolean + { + this._code = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._code = wrapper.readInt(); + + return true; + } + + public get code(): number + { + return this._code; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/catalog/CatalogRedeemVoucherErrorParser.ts b/src/nitro/communication/messages/parser/catalog/CatalogRedeemVoucherErrorParser.ts new file mode 100644 index 00000000..893cc7ed --- /dev/null +++ b/src/nitro/communication/messages/parser/catalog/CatalogRedeemVoucherErrorParser.ts @@ -0,0 +1,27 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; + +export class CatalogRedeemVoucherErrorParser implements IMessageParser +{ + private _errorCode:string = ''; + + public flush(): boolean + { + this._errorCode = ''; + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._errorCode = wrapper.readString(); + + return true; + } + + public get errorCode():string + { + return this._errorCode; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/catalog/CatalogRedeemVoucherOkParser.ts b/src/nitro/communication/messages/parser/catalog/CatalogRedeemVoucherOkParser.ts new file mode 100644 index 00000000..5f28983a --- /dev/null +++ b/src/nitro/communication/messages/parser/catalog/CatalogRedeemVoucherOkParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; + +export class CatalogRedeemVoucherOkParser implements IMessageParser +{ + private _productName:string = ''; + private _productDescription:string = ''; + + public flush(): boolean + { + this._productDescription = ''; + this._productName = ''; + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._productDescription = wrapper.readString(); + this._productName = wrapper.readString(); + + return true; + } + + public get productName():string + { + return this._productName; + } + + public get productDescription():string + { + return this._productDescription; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/catalog/CatalogSearchParser.ts b/src/nitro/communication/messages/parser/catalog/CatalogSearchParser.ts new file mode 100644 index 00000000..a415ae42 --- /dev/null +++ b/src/nitro/communication/messages/parser/catalog/CatalogSearchParser.ts @@ -0,0 +1,29 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; +import { CatalogPageOfferData } from './utils/CatalogPageOfferData'; + +export class CatalogSearchParser implements IMessageParser +{ + private _offer: CatalogPageOfferData; + + public flush(): boolean + { + this._offer = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._offer = new CatalogPageOfferData(wrapper); + + return true; + } + + public get offer(): CatalogPageOfferData + { + return this._offer; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/catalog/CatalogSoldOutParser.ts b/src/nitro/communication/messages/parser/catalog/CatalogSoldOutParser.ts new file mode 100644 index 00000000..b864b5b9 --- /dev/null +++ b/src/nitro/communication/messages/parser/catalog/CatalogSoldOutParser.ts @@ -0,0 +1,17 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; + +export class CatalogSoldOutParser implements IMessageParser +{ + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + return true; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/catalog/CatalogUpdatedParser.ts b/src/nitro/communication/messages/parser/catalog/CatalogUpdatedParser.ts new file mode 100644 index 00000000..07d5f654 --- /dev/null +++ b/src/nitro/communication/messages/parser/catalog/CatalogUpdatedParser.ts @@ -0,0 +1,37 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; + +export class CatalogUpdatedParser implements IMessageParser +{ + private _instantlyRefreshCatalogue: boolean; + private _newFurniDataHash: string; + + public flush(): boolean + { + this._instantlyRefreshCatalogue = false; + this._newFurniDataHash = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._instantlyRefreshCatalogue = wrapper.readBoolean(); + + if(wrapper.bytesAvailable) this._newFurniDataHash = wrapper.readString(); + + return true; + } + + public get instantlyRefreshCatalogue(): boolean + { + return this._instantlyRefreshCatalogue; + } + + public get newFurniDataHash(): string + { + return this._newFurniDataHash; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/catalog/utils/CatalogClubOfferData.ts b/src/nitro/communication/messages/parser/catalog/utils/CatalogClubOfferData.ts new file mode 100644 index 00000000..0d0c91a6 --- /dev/null +++ b/src/nitro/communication/messages/parser/catalog/utils/CatalogClubOfferData.ts @@ -0,0 +1,134 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; + +export class CatalogClubOfferData +{ + private _offerId: number; + private _productCode: string; + private _priceCredits: number; + private _priceActivityPoints: number; + private _priceActivityPointsType: number; + private _vip: boolean; + private _months: number; + private _extraDays: number; + private _daysLeftAfterPurchase: number; + private _year: number; + private _month: number; + private _day: number; + private _giftable: boolean; + + constructor(wrapper: IMessageDataWrapper) + { + if(!wrapper) throw new Error('invalid_wrapper'); + + this.flush(); + this.parse(wrapper); + } + + public flush(): boolean + { + this._offerId = -1; + this._productCode = null; + this._priceCredits = 0; + this._priceActivityPoints = 0; + this._priceActivityPointsType = 0; + this._vip = false; + this._months = 0; + this._extraDays = 0; + this._daysLeftAfterPurchase = 0; + this._year = 0; + this._month = 0; + this._day = 0; + this._giftable = false; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._offerId = wrapper.readInt(); + this._productCode = wrapper.readString(); + + wrapper.readBoolean(); + + this._priceCredits = wrapper.readInt(); + this._priceActivityPoints = wrapper.readInt(); + this._priceActivityPointsType = wrapper.readInt(); + this._vip = wrapper.readBoolean(); + this._months = wrapper.readInt(); + this._extraDays = wrapper.readInt(); + this._giftable = wrapper.readBoolean(); + this._daysLeftAfterPurchase = wrapper.readInt(); + this._year = wrapper.readInt(); + this._month = wrapper.readInt(); + this._day = wrapper.readInt(); + + return true; + } + + public get offerId(): number + { + return this._offerId; + } + + public get productCode(): string + { + return this._productCode; + } + + public get priceCredits(): number + { + return this._priceCredits; + } + + public get priceActivityPoints(): number + { + return this._priceActivityPoints; + } + + public get priceActivityPointsType(): number + { + return this._priceActivityPointsType; + } + + public get vip(): boolean + { + return this._vip; + } + + public get months(): number + { + return this._months; + } + + public get extraDays(): number + { + return this._extraDays; + } + + public get daysLeftAfterPurchase(): number + { + return this._daysLeftAfterPurchase; + } + + public get year(): number + { + return this._year; + } + + public get month(): number + { + return this._month; + } + + public get day(): number + { + return this._day; + } + + public get giftable(): boolean + { + return this._giftable; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/catalog/utils/CatalogFrontPageItem.ts b/src/nitro/communication/messages/parser/catalog/utils/CatalogFrontPageItem.ts new file mode 100644 index 00000000..bc601103 --- /dev/null +++ b/src/nitro/communication/messages/parser/catalog/utils/CatalogFrontPageItem.ts @@ -0,0 +1,109 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { Nitro } from '../../../../../Nitro'; + +export class CatalogFrontPageItem +{ + public static ITEM_CATALOGUE_PAGE: number = 0; + public static ITEM_PRODUCT_OFFER: number = 1; + public static ITEM_IAP: number = 2; + + private _type: number; + private _position: number; + private _itemName: string; + private _itemPromoImage: string; + private _catalogPageLocation: string; + private _productCode: string; + private _productOfferId: number; + private _expirationTime: number; + + constructor(wrapper: IMessageDataWrapper) + { + if(!wrapper) throw new Error('invalid_wrapper'); + + this.flush(); + this.parse(wrapper); + } + + public flush(): boolean + { + this._type = -1; + this._position = null; + this._itemName = null; + this._itemPromoImage = null; + this._catalogPageLocation = null; + this._productCode = null; + this._productOfferId = 0; + this._expirationTime = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._position = wrapper.readInt(); + this._itemName = wrapper.readString(); + this._itemPromoImage = wrapper.readString(); + this._type = wrapper.readInt(); + + switch(this._type) + { + case CatalogFrontPageItem.ITEM_CATALOGUE_PAGE: + this._catalogPageLocation = wrapper.readString(); + break; + case CatalogFrontPageItem.ITEM_PRODUCT_OFFER: + this._productOfferId = wrapper.readInt(); + break; + case CatalogFrontPageItem.ITEM_IAP: + this._productCode = wrapper.readString(); + break; + } + + const time = wrapper.readInt(); + + this._expirationTime = ((time > 0) ? ((time * 1000) + Nitro.instance.time) : 0); + + return true; + } + + public get type(): number + { + return this._type; + } + + public get position(): number + { + return this._position; + } + + public get itemName(): string + { + return this._itemName; + } + + public get itemPromoImage(): string + { + return this._itemPromoImage; + } + + public get catalogPageLocation(): string + { + return this._catalogPageLocation; + } + + public get productCode(): string + { + return this._productCode; + } + + public get productOfferId(): number + { + return this._productOfferId; + } + + public get expirationTime(): number + { + return this._expirationTime; + } +} diff --git a/src/nitro/communication/messages/parser/catalog/utils/CatalogGroupData.ts b/src/nitro/communication/messages/parser/catalog/utils/CatalogGroupData.ts new file mode 100644 index 00000000..db3839fd --- /dev/null +++ b/src/nitro/communication/messages/parser/catalog/utils/CatalogGroupData.ts @@ -0,0 +1,91 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; + +export class CatalogGroupData +{ + private _id: number; + private _title: string; + private _badge: string; + private _colorA: string; + private _colorB: string; + private _isOwner: boolean; + private _ownerId: number; + private _hasForum: boolean; + + constructor(wrapper: IMessageDataWrapper) + { + if(!wrapper) throw new Error('invalid_wrapper'); + + this.flush(); + this.parse(wrapper); + } + + public flush(): boolean + { + this._id = 0; + this._title = null; + this._badge = null; + this._colorA = null; + this._colorB = null; + this._isOwner = false; + this._ownerId = 0; + this._hasForum = false; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._id = wrapper.readInt(); + this._title = wrapper.readString(); + this._badge = wrapper.readString(); + this._colorA = wrapper.readString(); + this._colorB = wrapper.readString(); + this._isOwner = wrapper.readBoolean(); + this._ownerId = wrapper.readInt(); + this._hasForum = wrapper.readBoolean(); + + return true; + } + + public get id(): number + { + return this._id; + } + + public get title(): string + { + return this._title; + } + + public get badge(): string + { + return this._badge; + } + + public get colorA(): string + { + return this._colorA; + } + + public get colorB(): string + { + return this._colorB; + } + + public get isOwner(): boolean + { + return this._isOwner; + } + + public get ownerId(): number + { + return this._ownerId; + } + + public get hasForum(): boolean + { + return this._hasForum; + } +} diff --git a/src/nitro/communication/messages/parser/catalog/utils/CatalogLocalizationData.ts b/src/nitro/communication/messages/parser/catalog/utils/CatalogLocalizationData.ts new file mode 100644 index 00000000..aae770de --- /dev/null +++ b/src/nitro/communication/messages/parser/catalog/utils/CatalogLocalizationData.ts @@ -0,0 +1,59 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { ICatalogLocalizationData } from './ICatalogLocalizationData'; + +export class CatalogLocalizationData implements ICatalogLocalizationData +{ + private _images: string[]; + private _texts: string[]; + + constructor(wrapper: IMessageDataWrapper) + { + if(!wrapper) throw new Error('invalid_wrapper'); + + this.flush(); + this.parse(wrapper); + } + + public flush(): boolean + { + this._images = []; + this._texts = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + let totalImages = wrapper.readInt(); + + while(totalImages > 0) + { + this._images.push(wrapper.readString()); + + totalImages--; + } + + let totalTexts = wrapper.readInt(); + + while(totalTexts > 0) + { + this._texts.push(wrapper.readString()); + + totalTexts--; + } + + return true; + } + + public get images(): string[] + { + return this._images; + } + + public get texts(): string[] + { + return this._texts; + } +} diff --git a/src/nitro/communication/messages/parser/catalog/utils/CatalogPageData.ts b/src/nitro/communication/messages/parser/catalog/utils/CatalogPageData.ts new file mode 100644 index 00000000..91150574 --- /dev/null +++ b/src/nitro/communication/messages/parser/catalog/utils/CatalogPageData.ts @@ -0,0 +1,100 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { ICatalogPageData } from './ICatalogPageData'; + +export class CatalogPageData implements ICatalogPageData +{ + private _visible: boolean; + private _icon: number; + private _pageId: number; + private _pageName: string; + private _localization: string; + private _children: CatalogPageData[]; + private _offerIds: number[]; + + constructor(wrapper: IMessageDataWrapper) + { + if(!wrapper) throw new Error('invalid_wrapper'); + + this.flush(); + this.parse(wrapper); + } + + public flush(): boolean + { + this._visible = false; + this._icon = 0; + this._pageId = -1; + this._pageName = null; + this._localization = null; + this._children = []; + this._offerIds = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._visible = wrapper.readBoolean(); + this._icon = wrapper.readInt(); + this._pageId = wrapper.readInt(); + this._pageName = wrapper.readString(); + this._localization = wrapper.readString(); + + let totalOffers = wrapper.readInt(); + + while(totalOffers > 0) + { + this._offerIds.push(wrapper.readInt()); + + totalOffers--; + } + + let totalChildren = wrapper.readInt(); + + while(totalChildren > 0) + { + this._children.push(new CatalogPageData(wrapper)); + + totalChildren--; + } + + return true; + } + + public get visible(): boolean + { + return this._visible; + } + + public get icon(): number + { + return this._icon; + } + + public get pageId(): number + { + return this._pageId; + } + + public get pageName(): string + { + return this._pageName; + } + + public get localization(): string + { + return this._localization; + } + + public get children(): CatalogPageData[] + { + return this._children; + } + + public get offerIds(): number[] + { + return this._offerIds; + } +} diff --git a/src/nitro/communication/messages/parser/catalog/utils/CatalogPageOfferData.ts b/src/nitro/communication/messages/parser/catalog/utils/CatalogPageOfferData.ts new file mode 100644 index 00000000..5690315e --- /dev/null +++ b/src/nitro/communication/messages/parser/catalog/utils/CatalogPageOfferData.ts @@ -0,0 +1,133 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { CatalogProductOfferData } from './CatalogProductOfferData'; + +export class CatalogPageOfferData +{ + private _offerId: number; + private _localizationId: string; + private _rent: boolean; + private _priceCredits: number; + private _priceActivityPoints: number; + private _priceActivityPointsType: number; + private _clubLevel: number; + private _giftable: boolean; + private _bundlePurchaseAllowed: boolean; + private _isPet: boolean; + private _previewImage: string; + private _products: CatalogProductOfferData[]; + + constructor(wrapper: IMessageDataWrapper) + { + if(!wrapper) throw new Error('invalid_wrapper'); + + this.flush(); + this.parse(wrapper); + } + + public flush(): boolean + { + this._offerId = -1; + this._localizationId = null; + this._rent = false; + this._priceCredits = 0; + this._priceActivityPoints = 0; + this._priceActivityPointsType = 0; + this._clubLevel = 0; + this._giftable = false; + this._bundlePurchaseAllowed = false; + this._isPet = false; + this._previewImage = null; + this._products = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._offerId = wrapper.readInt(); + this._localizationId = wrapper.readString(); + this._rent = wrapper.readBoolean(); + this._priceCredits = wrapper.readInt(); + this._priceActivityPoints = wrapper.readInt(); + this._priceActivityPointsType = wrapper.readInt(); + this._giftable = wrapper.readBoolean(); + + let totalProducts = wrapper.readInt(); + + while(totalProducts > 0) + { + this._products.push(new CatalogProductOfferData(wrapper)); + + totalProducts--; + } + + this._clubLevel = wrapper.readInt(); + this._bundlePurchaseAllowed = wrapper.readBoolean(); + this._isPet = wrapper.readBoolean(); + this._previewImage = wrapper.readString(); + + return true; + } + + public get offerId(): number + { + return this._offerId; + } + + public get localizationId(): string + { + return this._localizationId; + } + + public get rent(): boolean + { + return this._rent; + } + + public get priceCredits(): number + { + return this._priceCredits; + } + + public get priceActivityPoints(): number + { + return this._priceActivityPoints; + } + + public get priceActivityPointsType(): number + { + return this._priceActivityPointsType; + } + + public get clubLevel(): number + { + return this._clubLevel; + } + + public get giftable(): boolean + { + return this._giftable; + } + + public get bundlePurchaseAllowed(): boolean + { + return this._bundlePurchaseAllowed; + } + + public get isPet(): boolean + { + return this._isPet; + } + + public get previewImage(): string + { + return this._previewImage; + } + + public get products(): CatalogProductOfferData[] + { + return this._products; + } +} diff --git a/src/nitro/communication/messages/parser/catalog/utils/CatalogProductOfferData.ts b/src/nitro/communication/messages/parser/catalog/utils/CatalogProductOfferData.ts new file mode 100644 index 00000000..425baeea --- /dev/null +++ b/src/nitro/communication/messages/parser/catalog/utils/CatalogProductOfferData.ts @@ -0,0 +1,98 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; + +export class CatalogProductOfferData +{ + public static I: string = 'i'; + public static S: string = 's'; + public static E: string = 'e'; + public static B: string = 'b'; + + private _productType: string; + private _furniClassId: number; + private _extraParam: string; + private _productCount: number; + private _uniqueLimitedItem: boolean; + private _uniqueLimitedItemSeriesSize: number; + private _uniqueLimitedItemsLeft: number; + + constructor(wrapper: IMessageDataWrapper) + { + if(!wrapper) throw new Error('invalid_wrapper'); + + this.flush(); + this.parse(wrapper); + } + + public flush(): boolean + { + this._productType = null; + this._furniClassId = -1; + this._extraParam = null; + this._productCount = 0; + this._uniqueLimitedItem = false; + this._uniqueLimitedItemSeriesSize = 0; + this._uniqueLimitedItemsLeft = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + this._productType = wrapper.readString(); + + switch(this._productType) + { + case CatalogProductOfferData.B: + this._extraParam = wrapper.readString(); + this._productCount = 1; + return true; + default: + this._furniClassId = wrapper.readInt(); + this._extraParam = wrapper.readString(); + this._productCount = wrapper.readInt(); + this._uniqueLimitedItem = wrapper.readBoolean(); + + if(this._uniqueLimitedItem) + { + this._uniqueLimitedItemSeriesSize = wrapper.readInt(); + this._uniqueLimitedItemsLeft = wrapper.readInt(); + } + return true; + } + } + + public get productType(): string + { + return this._productType; + } + + public get furniClassId(): number + { + return this._furniClassId; + } + + public get extraParam(): string + { + return this._extraParam; + } + + public get productCount(): number + { + return this._productCount; + } + + public get uniqueLimitedItem(): boolean + { + return this._uniqueLimitedItem; + } + + public get uniqueLimitedSeriesSize(): number + { + return this._uniqueLimitedItemSeriesSize; + } + + public get uniqueLimitedItemsLeft(): number + { + return this._uniqueLimitedItemsLeft; + } +} diff --git a/src/nitro/communication/messages/parser/catalog/utils/CatalogPurchaseData.ts b/src/nitro/communication/messages/parser/catalog/utils/CatalogPurchaseData.ts new file mode 100644 index 00000000..f611e7ab --- /dev/null +++ b/src/nitro/communication/messages/parser/catalog/utils/CatalogPurchaseData.ts @@ -0,0 +1,117 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { CatalogProductOfferData } from './CatalogProductOfferData'; + +export class CatalogPurchaseData +{ + private _offerId: number; + private _localizationId: string; + private _rent: boolean; + private _priceCredits: number; + private _priceActivityPoints: number; + private _priceActivityPointsType: number; + private _clubLevel: number; + private _giftable: boolean; + private _bundlePurchaseAllowed: boolean; + private _products: CatalogProductOfferData[]; + + constructor(wrapper: IMessageDataWrapper) + { + if(!wrapper) throw new Error('invalid_wrapper'); + + this.flush(); + this.parse(wrapper); + } + + public flush(): boolean + { + this._offerId = -1; + this._localizationId = null; + this._rent = false; + this._priceCredits = 0; + this._priceActivityPoints = 0; + this._priceActivityPointsType = 0; + this._clubLevel = 0; + this._giftable = false; + this._bundlePurchaseAllowed = false; + this._products = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._offerId = wrapper.readInt(); + this._localizationId = wrapper.readString(); + this._rent = wrapper.readBoolean(); + this._priceCredits = wrapper.readInt(); + this._priceActivityPoints = wrapper.readInt(); + this._priceActivityPointsType = wrapper.readInt(); + this._giftable = wrapper.readBoolean(); + + let totalProducts = wrapper.readInt(); + + while(totalProducts > 0) + { + this._products.push(new CatalogProductOfferData(wrapper)); + + totalProducts--; + } + + this._clubLevel = wrapper.readInt(); + this._bundlePurchaseAllowed = wrapper.readBoolean(); + + return true; + } + + public get offerId(): number + { + return this._offerId; + } + + public get localizationId(): string + { + return this._localizationId; + } + + public get rent(): boolean + { + return this._rent; + } + + public get priceCredits(): number + { + return this._priceCredits; + } + + public get priceActivityPoints(): number + { + return this._priceActivityPoints; + } + + public get priceActivityPointsType(): number + { + return this._priceActivityPointsType; + } + + public get clubLevel(): number + { + return this._clubLevel; + } + + public get giftable(): boolean + { + return this._giftable; + } + + public get bundlePurchaseAllowed(): boolean + { + return this._bundlePurchaseAllowed; + } + + public get products(): CatalogProductOfferData[] + { + return this._products; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/catalog/utils/CatalogSearchData.ts b/src/nitro/communication/messages/parser/catalog/utils/CatalogSearchData.ts new file mode 100644 index 00000000..c5c424a0 --- /dev/null +++ b/src/nitro/communication/messages/parser/catalog/utils/CatalogSearchData.ts @@ -0,0 +1,46 @@ +import { ICatalogPageData } from './ICatalogPageData'; + +export class CatalogSearchData implements ICatalogPageData +{ + private _children: ICatalogPageData[]; + constructor(pages: ICatalogPageData[]) + { + this._children = pages; + } + + public get children(): ICatalogPageData[] + { + return this._children; + } + + public get icon(): number + { + return -1; + } + + public get localization(): string + { + return ''; + } + + public get offerIds(): number[] + { + return []; + } + + public get pageId(): number + { + return -1; + } + + public get pageName(): string + { + return ''; + } + + public get visible(): boolean + { + return true; + } + +} diff --git a/src/nitro/communication/messages/parser/catalog/utils/ICatalogLocalizationData.ts b/src/nitro/communication/messages/parser/catalog/utils/ICatalogLocalizationData.ts new file mode 100644 index 00000000..c199e565 --- /dev/null +++ b/src/nitro/communication/messages/parser/catalog/utils/ICatalogLocalizationData.ts @@ -0,0 +1,5 @@ +export interface ICatalogLocalizationData +{ + readonly images: string[]; + readonly texts: string[]; +} diff --git a/src/nitro/communication/messages/parser/catalog/utils/ICatalogPageData.ts b/src/nitro/communication/messages/parser/catalog/utils/ICatalogPageData.ts new file mode 100644 index 00000000..8da1f031 --- /dev/null +++ b/src/nitro/communication/messages/parser/catalog/utils/ICatalogPageData.ts @@ -0,0 +1,10 @@ +export interface ICatalogPageData +{ + visible: boolean; + icon: number; + pageId: number; + pageName: string; + localization: string; + children: ICatalogPageData[]; + offerIds: number[]; +} diff --git a/src/nitro/communication/messages/parser/catalog/utils/ICatalogPageParser.ts b/src/nitro/communication/messages/parser/catalog/utils/ICatalogPageParser.ts new file mode 100644 index 00000000..9c181c10 --- /dev/null +++ b/src/nitro/communication/messages/parser/catalog/utils/ICatalogPageParser.ts @@ -0,0 +1,17 @@ +import { CatalogLocalizationData } from './CatalogLocalizationData'; +import { CatalogPageOfferData } from './CatalogPageOfferData'; +import { CatalogFrontPageItem } from './CatalogFrontPageItem'; +import { ICatalogLocalizationData } from './ICatalogLocalizationData'; + +export interface ICatalogPageParser +{ + readonly pageId: number; + readonly catalogType: string; + readonly layoutCode: string; + readonly localization: ICatalogLocalizationData; + readonly offers: CatalogPageOfferData[]; + readonly offerId: number; + readonly acceptSeasonCurrencyAsCredits: boolean; + readonly frontPageItems: CatalogFrontPageItem[]; + +} diff --git a/src/nitro/communication/messages/parser/catalog/utils/_Str_5178.ts b/src/nitro/communication/messages/parser/catalog/utils/_Str_5178.ts new file mode 100644 index 00000000..71500196 --- /dev/null +++ b/src/nitro/communication/messages/parser/catalog/utils/_Str_5178.ts @@ -0,0 +1,64 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; + +export class _Str_5178 +{ + private _Str_2507:number; + private _Str_6052:boolean; + private _Str_693:boolean; + private _Str_19803:number; + + constructor(wrapper: IMessageDataWrapper) + { + if(!wrapper) throw new Error('invalid_wrapper'); + + this.parse(wrapper); + } + + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._Str_2507 = wrapper.readInt(); + this._Str_6052 = wrapper.readBoolean(); + this._Str_19803 = wrapper.readInt(); + this._Str_693 = wrapper.readBoolean(); + return true; + } + + public get offerId():number + { + return this._Str_2507; + } + + public get _Str_12313():boolean + { + return this._Str_6052; + } + + public get isClubOnly(): boolean + { + return this._Str_6052; + } + public get isSelectable():boolean + { + return this._Str_693; + } + + public get _Str_21146():number + { + return this._Str_19803; + } + + public get availableInDays(): number + { + return this._Str_19803; + } + + public get isAvailable(): boolean + { + return this._Str_693; + } + + +} diff --git a/src/nitro/communication/messages/parser/client/ClientPingParser.ts b/src/nitro/communication/messages/parser/client/ClientPingParser.ts new file mode 100644 index 00000000..743609f1 --- /dev/null +++ b/src/nitro/communication/messages/parser/client/ClientPingParser.ts @@ -0,0 +1,17 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; + +export class ClientPingParser implements IMessageParser +{ + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + return true; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/desktop/DesktopViewParser.ts b/src/nitro/communication/messages/parser/desktop/DesktopViewParser.ts new file mode 100644 index 00000000..f994c710 --- /dev/null +++ b/src/nitro/communication/messages/parser/desktop/DesktopViewParser.ts @@ -0,0 +1,17 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; + +export class DesktopViewParser implements IMessageParser +{ + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + return true; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/friendlist/AcceptFriendResultParser.ts b/src/nitro/communication/messages/parser/friendlist/AcceptFriendResultParser.ts new file mode 100644 index 00000000..ec15fb4a --- /dev/null +++ b/src/nitro/communication/messages/parser/friendlist/AcceptFriendResultParser.ts @@ -0,0 +1,36 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; +import { AcceptFriendFailerData } from '../../incoming/friendlist/AcceptFriendFailureData'; + +export class AcceptFriendResultParser implements IMessageParser +{ + private _failuers: AcceptFriendFailerData[]; + + public flush(): boolean + { + this._failuers = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + let totalFailures = wrapper.readInt(); + + while(totalFailures > 0) + { + this._failuers.push(new AcceptFriendFailerData(wrapper)); + + totalFailures--; + } + + return true; + } + + public get failures(): AcceptFriendFailerData[] + { + return this._failuers; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/friendlist/FindFriendsProcessResultParser.ts b/src/nitro/communication/messages/parser/friendlist/FindFriendsProcessResultParser.ts new file mode 100644 index 00000000..ec25eee7 --- /dev/null +++ b/src/nitro/communication/messages/parser/friendlist/FindFriendsProcessResultParser.ts @@ -0,0 +1,28 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; + +export class FindFriendsProcessResultParser implements IMessageParser +{ + private _success: boolean; + + public flush(): boolean + { + this._success = false; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._success = wrapper.readBoolean(); + + return true; + } + + public get success(): boolean + { + return this._success; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/friendlist/FollowFriendFailedParser.ts b/src/nitro/communication/messages/parser/friendlist/FollowFriendFailedParser.ts new file mode 100644 index 00000000..254838b0 --- /dev/null +++ b/src/nitro/communication/messages/parser/friendlist/FollowFriendFailedParser.ts @@ -0,0 +1,28 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; + +export class FollowFriendFailedParser implements IMessageParser +{ + private _errorCode: number; + + public flush(): boolean + { + this._errorCode = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._errorCode = wrapper.readInt(); + + return true; + } + + public get errorCode(): number + { + return this._errorCode; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/friendlist/FriendListFragmentMessageParser.ts b/src/nitro/communication/messages/parser/friendlist/FriendListFragmentMessageParser.ts new file mode 100644 index 00000000..0efb5889 --- /dev/null +++ b/src/nitro/communication/messages/parser/friendlist/FriendListFragmentMessageParser.ts @@ -0,0 +1,53 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; +import { FriendParser } from '../../incoming/friendlist/FriendParser'; + +export class FriendListFragmentParser implements IMessageParser +{ + private _totalFragments: number; + private _fragmentNumber: number; + private _fragment: FriendParser[]; + + public flush(): boolean + { + this._totalFragments = 0; + this._fragmentNumber = 0; + this._fragment = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._totalFragments = wrapper.readInt(); + this._fragmentNumber = wrapper.readInt(); + + let totalFriends = wrapper.readInt(); + + while(totalFriends > 0) + { + this._fragment.push(new FriendParser(wrapper)); + + totalFriends--; + } + + return true; + } + + public get totalFragments(): number + { + return this._totalFragments; + } + + public get fragmentNumber(): number + { + return this._fragmentNumber; + } + + public get fragment(): FriendParser[] + { + return this._fragment; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/friendlist/FriendListUpdateParser.ts b/src/nitro/communication/messages/parser/friendlist/FriendListUpdateParser.ts new file mode 100644 index 00000000..b15e0f5a --- /dev/null +++ b/src/nitro/communication/messages/parser/friendlist/FriendListUpdateParser.ts @@ -0,0 +1,82 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; +import { FriendCategoryData } from '../../incoming/friendlist/FriendCategoryData'; +import { FriendParser } from '../../incoming/friendlist/FriendParser'; + +export class FriendListUpdateParser implements IMessageParser +{ + private _categories: FriendCategoryData[]; + private _removedFriendIds: number[]; + private _addedFriends: FriendParser[]; + private _updatedFriends: FriendParser[]; + + public flush(): boolean + { + this._categories = []; + this._removedFriendIds = []; + this._addedFriends = []; + this._updatedFriends = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + let totalCategories = wrapper.readInt(); + + while(totalCategories > 0) + { + this._categories.push(new FriendCategoryData(wrapper)); + + totalCategories--; + } + + let totalUpdates = wrapper.readInt(); + + while(totalUpdates > 0) + { + const type = wrapper.readInt(); + + if(type === -1) + { + this._removedFriendIds.push(wrapper.readInt()); + } + + else if(type === 0) + { + this._updatedFriends.push(new FriendParser(wrapper)); + } + + else if(type === 1) + { + this._addedFriends.push(new FriendParser(wrapper)); + } + + totalUpdates--; + } + + return true; + } + + public get categories(): FriendCategoryData[] + { + return this._categories; + } + + public get removedFriendIds(): number[] + { + return this._removedFriendIds; + } + + public get addedFriends(): FriendParser[] + { + return this._addedFriends; + } + + public get updatedFriends(): FriendParser[] + { + return this._updatedFriends; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/friendlist/FriendNotificationParser.ts b/src/nitro/communication/messages/parser/friendlist/FriendNotificationParser.ts new file mode 100644 index 00000000..ec5a4899 --- /dev/null +++ b/src/nitro/communication/messages/parser/friendlist/FriendNotificationParser.ts @@ -0,0 +1,44 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; + +export class FriendNotificationParser implements IMessageParser +{ + private _typeCode: number; + private _avatarId: number; + private _message: string; + + public flush(): boolean + { + this._typeCode = -1; + this._avatarId = 0; + this._message = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._typeCode = wrapper.readInt(); + this._avatarId = wrapper.readInt(); + this._message = wrapper.readString(); + + return true; + } + + public get typeCode(): number + { + return this._typeCode; + } + + public get avatarId(): number + { + return this._avatarId; + } + + public get message(): string + { + return this._message; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/friendlist/FriendRequestsParser.ts b/src/nitro/communication/messages/parser/friendlist/FriendRequestsParser.ts new file mode 100644 index 00000000..e45fda29 --- /dev/null +++ b/src/nitro/communication/messages/parser/friendlist/FriendRequestsParser.ts @@ -0,0 +1,45 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; +import { FriendRequestData } from '../../incoming/friendlist/FriendRequestData'; + +export class FriendRequestsParser implements IMessageParser +{ + private _totalRequests: number; + private _requests: FriendRequestData[]; + + public flush(): boolean + { + this._totalRequests = 0; + this._requests = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._totalRequests = wrapper.readInt(); + + let totalRequests = wrapper.readInt(); + + while(totalRequests > 0) + { + this._requests.push(new FriendRequestData(wrapper)); + + totalRequests--; + } + + return true; + } + + public get totalRequests(): number + { + return this._totalRequests; + } + + public get requests(): FriendRequestData[] + { + return this._requests; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/friendlist/HabboSearchResultParser.ts b/src/nitro/communication/messages/parser/friendlist/HabboSearchResultParser.ts new file mode 100644 index 00000000..f832ed62 --- /dev/null +++ b/src/nitro/communication/messages/parser/friendlist/HabboSearchResultParser.ts @@ -0,0 +1,52 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; +import { HabboSearchResultData } from '../../incoming/friendlist/HabboSearchResultData'; + +export class HabboSearchResultParser implements IMessageParser +{ + private _friends: HabboSearchResultData[]; + private _others: HabboSearchResultData[]; + + public flush(): boolean + { + this._friends = []; + this._others = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + let totalFriends = wrapper.readInt(); + + while(totalFriends > 0) + { + this._friends.push(new HabboSearchResultData(wrapper)); + + totalFriends--; + } + + let totalOthers = wrapper.readInt(); + + while(totalOthers > 0) + { + this._others.push(new HabboSearchResultData(wrapper)); + + totalOthers--; + } + + return true; + } + + public get friends(): HabboSearchResultData[] + { + return this._friends; + } + + public get others(): HabboSearchResultData[] + { + return this._others; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/friendlist/InstantMessageErrorParser.ts b/src/nitro/communication/messages/parser/friendlist/InstantMessageErrorParser.ts new file mode 100644 index 00000000..b3593b3a --- /dev/null +++ b/src/nitro/communication/messages/parser/friendlist/InstantMessageErrorParser.ts @@ -0,0 +1,44 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; + +export class InstantMessageErrorParser implements IMessageParser +{ + private _errorCode: number; + private _userId: number; + private _message: string; + + public flush(): boolean + { + this._errorCode = 0; + this._userId = 0; + this._message = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._errorCode = wrapper.readInt(); + this._userId = wrapper.readInt(); + this._message = wrapper.readString(); + + return true; + } + + public get errorCode(): number + { + return this._errorCode; + } + + public get userId(): number + { + return this._userId; + } + + public get message(): string + { + return this._message; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/friendlist/MessageErrorParser.ts b/src/nitro/communication/messages/parser/friendlist/MessageErrorParser.ts new file mode 100644 index 00000000..daa0204b --- /dev/null +++ b/src/nitro/communication/messages/parser/friendlist/MessageErrorParser.ts @@ -0,0 +1,36 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; + +export class MessageErrorParser implements IMessageParser +{ + private _clientMessageId: number; + private _errorCode: number; + + public flush(): boolean + { + this._clientMessageId = 0; + this._errorCode = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._clientMessageId = wrapper.readInt(); + this._errorCode = wrapper.readInt(); + + return true; + } + + public get clientMessageId(): number + { + return this._clientMessageId; + } + + public get errorCode(): number + { + return this._errorCode; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/friendlist/MessengerInitParser.ts b/src/nitro/communication/messages/parser/friendlist/MessengerInitParser.ts new file mode 100644 index 00000000..0a85b0fc --- /dev/null +++ b/src/nitro/communication/messages/parser/friendlist/MessengerInitParser.ts @@ -0,0 +1,60 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; +import { FriendCategoryData } from '../../incoming/friendlist/FriendCategoryData'; + +export class MessengerInitParser implements IMessageParser +{ + private _userFriendLimit: number; + private _normalFriendLimit: number; + private _extendedFriendLimit: number; + private _categories: FriendCategoryData[]; + + public flush(): boolean + { + this._userFriendLimit = 0; + this._normalFriendLimit = 0; + this._extendedFriendLimit = 0; + this._categories = []; + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._userFriendLimit = wrapper.readInt(); + this._normalFriendLimit = wrapper.readInt(); + this._extendedFriendLimit = wrapper.readInt(); + + let totalCategories = wrapper.readInt(); + + while(totalCategories > 0) + { + this._categories.push(new FriendCategoryData(wrapper)); + + totalCategories--; + } + + return true; + } + + public get userFriendLimit(): number + { + return this._userFriendLimit; + } + + public get normalFriendLimit(): number + { + return this._normalFriendLimit; + } + + public get extendedFriendLimit(): number + { + return this._extendedFriendLimit; + } + + public get categories(): FriendCategoryData[] + { + return this._categories; + } +} diff --git a/src/nitro/communication/messages/parser/friendlist/MiniMailNewMessageParser.ts b/src/nitro/communication/messages/parser/friendlist/MiniMailNewMessageParser.ts new file mode 100644 index 00000000..26ce3edc --- /dev/null +++ b/src/nitro/communication/messages/parser/friendlist/MiniMailNewMessageParser.ts @@ -0,0 +1,17 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; + +export class MiniMailNewMessageParser implements IMessageParser +{ + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + return true; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/friendlist/MiniMailUnreadCountParser.ts b/src/nitro/communication/messages/parser/friendlist/MiniMailUnreadCountParser.ts new file mode 100644 index 00000000..d9204650 --- /dev/null +++ b/src/nitro/communication/messages/parser/friendlist/MiniMailUnreadCountParser.ts @@ -0,0 +1,28 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; + +export class MiniMailUnreadCountParser implements IMessageParser +{ + private _count: number; + + public flush(): boolean + { + this._count = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._count = wrapper.readInt(); + + return true; + } + + public get count(): number + { + return this._count; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/friendlist/NewConsoleMessageParser.ts b/src/nitro/communication/messages/parser/friendlist/NewConsoleMessageParser.ts new file mode 100644 index 00000000..1a284240 --- /dev/null +++ b/src/nitro/communication/messages/parser/friendlist/NewConsoleMessageParser.ts @@ -0,0 +1,56 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; + +export class NewConsoleMessageParser implements IMessageParser +{ + private _senderId: number; + private _messageText: string; + private _secondsSinceSent: number; + private _extraData: string; + + public flush(): boolean + { + this._senderId = 0; + this._messageText = null; + this._secondsSinceSent = 0; + this._extraData = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._senderId = wrapper.readInt(); + this._messageText = wrapper.readString(); + this._secondsSinceSent = wrapper.readInt(); + + if(wrapper.bytesAvailable) + { + this._extraData = wrapper.readString(); + } + + return true; + } + + public get senderId(): number + { + return this._senderId; + } + + public get messageText(): string + { + return this._messageText; + } + + public get secondsSinceSent(): number + { + return this._secondsSinceSent; + } + + public get extraData(): string + { + return this._extraData; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/friendlist/NewFriendRequestMessageParser.ts b/src/nitro/communication/messages/parser/friendlist/NewFriendRequestMessageParser.ts new file mode 100644 index 00000000..4824a8bb --- /dev/null +++ b/src/nitro/communication/messages/parser/friendlist/NewFriendRequestMessageParser.ts @@ -0,0 +1,29 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; +import { FriendRequestData } from '../../incoming/friendlist/FriendRequestData'; + +export class NewFriendRequestParser implements IMessageParser +{ + private _request: FriendRequestData; + + public flush(): boolean + { + this._request = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._request = new FriendRequestData(wrapper); + + return true; + } + + public get request(): FriendRequestData + { + return this._request; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/friendlist/RoomInviteErrorParser.ts b/src/nitro/communication/messages/parser/friendlist/RoomInviteErrorParser.ts new file mode 100644 index 00000000..ae93d188 --- /dev/null +++ b/src/nitro/communication/messages/parser/friendlist/RoomInviteErrorParser.ts @@ -0,0 +1,44 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; + +export class RoomInviteErrorParser implements IMessageParser +{ + private _errorCode: number; + private _failedRecipients: number[]; + + public flush(): boolean + { + this._errorCode = 0; + this._failedRecipients = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._errorCode = wrapper.readInt(); + + let totalFailed = wrapper.readInt(); + + while(totalFailed > 0) + { + this._failedRecipients.push(wrapper.readInt()); + + totalFailed--; + } + + return true; + } + + public get errorCode(): number + { + return this._errorCode; + } + + public get failedRecipients(): number[] + { + return this._failedRecipients; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/friendlist/RoomInviteMessageParser.ts b/src/nitro/communication/messages/parser/friendlist/RoomInviteMessageParser.ts new file mode 100644 index 00000000..9c91a82a --- /dev/null +++ b/src/nitro/communication/messages/parser/friendlist/RoomInviteMessageParser.ts @@ -0,0 +1,36 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; + +export class RoomInviteParser implements IMessageParser +{ + private _senderId: number; + private _messageText: string; + + public flush(): boolean + { + this._senderId = 0; + this._messageText = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._senderId = wrapper.readInt(); + this._messageText = wrapper.readString(); + + return true; + } + + public get senderId(): number + { + return this._senderId; + } + + public get messageText(): string + { + return this._messageText; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/game/LoadGameUrlParser.ts b/src/nitro/communication/messages/parser/game/LoadGameUrlParser.ts new file mode 100644 index 00000000..d8d8b1ef --- /dev/null +++ b/src/nitro/communication/messages/parser/game/LoadGameUrlParser.ts @@ -0,0 +1,44 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; + +export class LoadGameUrlParser implements IMessageParser +{ + private _gameTypeId: number; + private _url: string; + private _gameClientId: string; + + public flush(): boolean + { + this._gameTypeId = 0; + this._url = null; + this._gameClientId = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._gameTypeId = wrapper.readInt(); + this._gameClientId = wrapper.readString(); + this._url = wrapper.readString(); + + return true; + } + + public get gameTypeId(): number + { + return this._gameTypeId; + } + + public get url(): string + { + return this._url; + } + + public get gameClientId(): string + { + return this._gameClientId; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/generic/GenericErrorParser.ts b/src/nitro/communication/messages/parser/generic/GenericErrorParser.ts new file mode 100644 index 00000000..2db53a35 --- /dev/null +++ b/src/nitro/communication/messages/parser/generic/GenericErrorParser.ts @@ -0,0 +1,27 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; + +export class GenericErrorParser implements IMessageParser +{ + private _errorCode: number; + + public flush(): boolean + { + this._errorCode = 0; + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._errorCode = wrapper.readInt(); + + return true; + } + + public get errorCode(): number + { + return this._errorCode; + } +} diff --git a/src/nitro/communication/messages/parser/group/GroupBadgePartsParser.ts b/src/nitro/communication/messages/parser/group/GroupBadgePartsParser.ts new file mode 100644 index 00000000..75c13ba8 --- /dev/null +++ b/src/nitro/communication/messages/parser/group/GroupBadgePartsParser.ts @@ -0,0 +1,110 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; + +export class GroupBadgePartsParser implements IMessageParser +{ + private _bases: Map; + private _symbols: Map; + private _partColors: Map; + private _colorsA: Map; + private _colorsB: Map; + + flush(): boolean + { + this._bases = new Map(); + this._symbols = new Map(); + this._partColors = new Map(); + this._colorsA = new Map(); + this._colorsB = new Map(); + + return true; + } + + parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + let basesCount = wrapper.readInt(); + + while(basesCount > 0) + { + const id = wrapper.readInt(); + const valueA = wrapper.readString(); + const valueB = wrapper.readString(); + + this._bases.set(id, [valueA, valueB]); + basesCount--; + } + + let symbolsCount = wrapper.readInt(); + + while(symbolsCount > 0) + { + const id = wrapper.readInt(); + const valueA = wrapper.readString(); + const valueB = wrapper.readString(); + + this._symbols.set(id, [valueA, valueB]); + symbolsCount--; + } + + let partColorsCount = wrapper.readInt(); + + while(partColorsCount > 0) + { + const id = wrapper.readInt(); + const color = wrapper.readString(); + + this._partColors.set(id, color); + partColorsCount--; + } + + let colorsACount = wrapper.readInt(); + + while(colorsACount > 0) + { + const id = wrapper.readInt(); + const color = wrapper.readString(); + + this._colorsA.set(id, color); + colorsACount--; + } + + let colorsBCount = wrapper.readInt(); + + while(colorsBCount > 0) + { + const id = wrapper.readInt(); + const color = wrapper.readString(); + + this._colorsB.set(id, color); + colorsBCount--; + } + return true; + } + + public get bases(): Map + { + return this._bases; + } + + public get symbols(): Map + { + return this._symbols; + } + + public get partColors(): Map + { + return this._partColors; + } + + public get colorsA(): Map + { + return this._colorsA; + } + + public get colorsB(): Map + { + return this._colorsB; + } +} diff --git a/src/nitro/communication/messages/parser/group/GroupBuyDataParser.ts b/src/nitro/communication/messages/parser/group/GroupBuyDataParser.ts new file mode 100644 index 00000000..ae7ef1de --- /dev/null +++ b/src/nitro/communication/messages/parser/group/GroupBuyDataParser.ts @@ -0,0 +1,46 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; + +export class GroupBuyDataParser implements IMessageParser +{ + private _groupCost: number; + private _availableRooms: Map; + + flush(): boolean + { + this._groupCost = 0; + this._availableRooms = new Map(); + + return true; + } + + parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._groupCost = wrapper.readInt(); + let availableRoomsCount = wrapper.readInt(); + + while(availableRoomsCount > 0) + { + const roomId = wrapper.readInt(); + const roomName = wrapper.readString(); + wrapper.readBoolean(); + + this._availableRooms.set(roomId, roomName); + + availableRoomsCount--; + } + return true; + } + + public get groupCost(): number + { + return this._groupCost; + } + + public get availableRooms(): Map + { + return this._availableRooms; + } +} diff --git a/src/nitro/communication/messages/parser/group/GroupConfirmMemberRemoveParser.ts b/src/nitro/communication/messages/parser/group/GroupConfirmMemberRemoveParser.ts new file mode 100644 index 00000000..510e3818 --- /dev/null +++ b/src/nitro/communication/messages/parser/group/GroupConfirmMemberRemoveParser.ts @@ -0,0 +1,36 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; + +export class GroupConfirmMemberRemoveParser implements IMessageParser +{ + private _userId: number; + private _furnitureCount: number; + + flush(): boolean + { + this._userId = 0; + this._furnitureCount = 0; + + return true; + } + + parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._userId = wrapper.readInt(); + this._furnitureCount = wrapper.readInt(); + + return true; + } + + public get userId(): number + { + return this._userId; + } + + public get furnitureCount(): number + { + return this._furnitureCount; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/group/GroupInformationParser.ts b/src/nitro/communication/messages/parser/group/GroupInformationParser.ts new file mode 100644 index 00000000..e4573ab7 --- /dev/null +++ b/src/nitro/communication/messages/parser/group/GroupInformationParser.ts @@ -0,0 +1,150 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; + +export class GroupInformationParser implements IMessageParser +{ + private _id: number; + private _type: number; + private _title: string; + private _description: string; + private _badge: string; + private _roomId: number; + private _roomName: string; + private _membershipType: number; + private _membersCount: number; + private _createdAt: string; + private _isOwner: boolean; + private _isAdmin: boolean; + private _ownerName: string; + private _flag: boolean; + private _canMembersDecorate: boolean; + private _pendingRequestsCount: number; + + public flush(): boolean + { + this._id = 0; + this._type = 0; + this._title = null; + this._description = null; + this._badge = null; + this._roomId = 0; + this._roomName = null; + this._membershipType = 0; + this._membersCount = 0; + this._createdAt = null; + this._isOwner = false; + this._isAdmin = false; + this._ownerName = null; + this._flag = false; + this._canMembersDecorate = false; + this._pendingRequestsCount = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._id = wrapper.readInt(); + wrapper.readBoolean(); + this._type = wrapper.readInt(); + this._title = wrapper.readString(); + this._description = wrapper.readString(); + this._badge = wrapper.readString(); + this._roomId = wrapper.readInt(); + this._roomName = wrapper.readString(); + this._membershipType = wrapper.readInt(); + this._membersCount = wrapper.readInt(); + wrapper.readBoolean(); + this._createdAt = wrapper.readString(); + this._isOwner = wrapper.readBoolean(); + this._isAdmin = wrapper.readBoolean(); + this._ownerName = wrapper.readString(); + this._flag = wrapper.readBoolean(); + this._canMembersDecorate = wrapper.readBoolean(); + this._pendingRequestsCount = wrapper.readInt(); + + return true; + } + + public get id(): number + { + return this._id; + } + + public get type(): number + { + return this._type; + } + + public get title(): string + { + return this._title; + } + + public get description(): string + { + return this._description; + } + + public get badge(): string + { + return this._badge; + } + + public get roomId(): number + { + return this._roomId; + } + + public get roomName(): string + { + return this._roomName; + } + + public get membershipType(): number + { + return this._membershipType; + } + + public get membersCount(): number + { + return this._membersCount; + } + + public get createdAt(): string + { + return this._createdAt; + } + + public get isOwner(): boolean + { + return this._isOwner; + } + + public get isAdmin(): boolean + { + return this._isAdmin; + } + + public get ownerName(): string + { + return this._ownerName; + } + + public get flag(): boolean + { + return this._flag; + } + + public get canMembersDecorate(): boolean + { + return this._canMembersDecorate; + } + + public get pendingRequestsCount(): number + { + return this._pendingRequestsCount; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/group/GroupMembersParser.ts b/src/nitro/communication/messages/parser/group/GroupMembersParser.ts new file mode 100644 index 00000000..8e2392c8 --- /dev/null +++ b/src/nitro/communication/messages/parser/group/GroupMembersParser.ts @@ -0,0 +1,117 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; +import GroupMemberParser from './utils/GroupMemberParser'; + +export class GroupMembersParser implements IMessageParser +{ + private _groupId: number; + private _groupTitle: string; + private _roomId: number; + private _badge: string; + private _totalMembersCount: number; + private _result: GroupMemberParser[]; + private _admin: boolean; + private _pageSize: number; + private _pageIndex: number; + private _level: number; + private _query: string; + + public flush(): boolean + { + this._groupId = 0; + this._groupTitle = null; + this._roomId = 0; + this._badge = null; + this._totalMembersCount = 0; + this._result = []; + this._admin = false; + this._pageSize = 0; + this._pageIndex = 0; + this._level = 0; + this._query = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._groupId = wrapper.readInt(); + this._groupTitle = wrapper.readString(); + this._roomId = wrapper.readInt(); + this._badge = wrapper.readString(); + this._totalMembersCount = wrapper.readInt(); + + let resultCount = wrapper.readInt(); + + while(resultCount > 0) + { + this._result.push(new GroupMemberParser(wrapper)); + + resultCount--; + } + + this._admin = wrapper.readBoolean(); + this._pageSize = wrapper.readInt(); + this._pageIndex = wrapper.readInt(); + this._level = wrapper.readInt(); + this._query = wrapper.readString(); + + return true; + } + + public get groupId(): number + { + return this._groupId; + } + public get groupTitle(): string + { + return this._groupTitle; + } + + public get roomId(): number + { + return this._roomId; + } + + public get badge(): string + { + return this._badge; + } + + public get totalMembersCount(): number + { + return this._totalMembersCount; + } + + public get result(): GroupMemberParser[] + { + return this._result; + } + + public get admin(): boolean + { + return this._admin; + } + + public get pageSize(): number + { + return this._pageSize; + } + + public get pageIndex(): number + { + return this._pageIndex; + } + + public get level(): number + { + return this._level; + } + + public get query(): string + { + return this._query; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/group/GroupSettingsParser.ts b/src/nitro/communication/messages/parser/group/GroupSettingsParser.ts new file mode 100644 index 00000000..f55c41b6 --- /dev/null +++ b/src/nitro/communication/messages/parser/group/GroupSettingsParser.ts @@ -0,0 +1,150 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; +import { GroupBadgePart } from './utils/GroupBadgePart'; + +export class GroupSettingsParser implements IMessageParser +{ + private _roomId: number; + private _roomName: string; + private _id: number; + private _title: string; + private _description: string; + private _colorA: number; + private _colorB: number; + private _state: number; + private _canMembersDecorate: boolean; + private _badgeParts: Map; + private _badgeCode: string; + private _membersCount: number; + + public flush(): boolean + { + this._roomId = 0; + this._roomName = null; + this._id = 0; + this._title = null; + this._description = null; + this._colorA = 0; + this._colorB = 0; + this._state = 0; + this._canMembersDecorate = false; + this._badgeParts = new Map(); + this._badgeCode = null; + this._membersCount = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + const hasRoomData = wrapper.readInt(); + + if(hasRoomData === 1) + { + this._roomId = wrapper.readInt(); + this._roomName = wrapper.readString(); + wrapper.readBoolean(); + } + + wrapper.readBoolean(); + + this._id = wrapper.readInt(); + this._title = wrapper.readString(); + this._description = wrapper.readString(); + + wrapper.readInt(); + + this._colorA = wrapper.readInt(); + this._colorB = wrapper.readInt(); + this._state = wrapper.readInt(); + this._canMembersDecorate = wrapper.readInt() === 0; + + wrapper.readBoolean(); + wrapper.readString(); + + const badgePartsCount = wrapper.readInt(); + + for(let i = 0; i < badgePartsCount; i++) + { + const part = new GroupBadgePart(i === 0); + + part.key = wrapper.readInt(); + part.color = wrapper.readInt(); + part.position = wrapper.readInt(); + + if(part.key === 0) + { + part.position = 4; + } + + this._badgeParts.set(i, part); + } + + this._badgeCode = wrapper.readString(); + this._membersCount = wrapper.readInt(); + + return true; + } + + public get roomId(): number + { + return this._roomId; + } + + public get roomName(): string + { + return this._roomName; + } + + public get id(): number + { + return this._id; + } + + public get title(): string + { + return this._title; + } + + public get description(): string + { + return this._description; + } + + public get colorA(): number + { + return this._colorA; + } + + public get colorB(): number + { + return this._colorB; + } + + public get state(): number + { + return this._state; + } + + public get canMembersDecorate(): boolean + { + return this._canMembersDecorate; + } + + public get badgeParts(): Map + { + return this._badgeParts; + } + + public get badgeCode(): string + { + return this._badgeCode; + } + + public get membersCount(): number + { + return this._membersCount; + } +} diff --git a/src/nitro/communication/messages/parser/group/utils/GroupBadgePart.ts b/src/nitro/communication/messages/parser/group/utils/GroupBadgePart.ts new file mode 100644 index 00000000..bc7010af --- /dev/null +++ b/src/nitro/communication/messages/parser/group/utils/GroupBadgePart.ts @@ -0,0 +1,22 @@ +export class GroupBadgePart +{ + public isBase: boolean; + public key: number; + public color: number; + public position: number; + + constructor(isBase: boolean) + { + this.isBase = isBase; + this.key = 0; + this.color = 0; + this.position = 4; + } + + public get code(): string + { + if(this.key === 0) return null; + + return (this.isBase ? 'b' : 's') + (this.key < 100 ? '0' : '') + (this.key < 10 ? '0' : '') + this.key + (this.color < 10 ? '0' : '') + this.color + this.position; + } +} diff --git a/src/nitro/communication/messages/parser/group/utils/GroupDataParser.ts b/src/nitro/communication/messages/parser/group/utils/GroupDataParser.ts new file mode 100644 index 00000000..991ada1b --- /dev/null +++ b/src/nitro/communication/messages/parser/group/utils/GroupDataParser.ts @@ -0,0 +1,91 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; + +export class GroupDataParser +{ + private _id: number; + private _title: string; + private _badge: string; + private _colorA: string; + private _colorB: string; + private _ownerOrFavorite: boolean; + private _ownerId: number; + private _hasForum: boolean; + + constructor(wrapper: IMessageDataWrapper) + { + if(!wrapper) throw new Error('invalid_wrapper'); + + this.flush(); + this.parse(wrapper); + } + + public flush(): boolean + { + this._id = 0; + this._title = null; + this._badge = null; + this._colorA = null; + this._colorB = null; + this._ownerOrFavorite = null; + this._ownerId = 0; + this._hasForum = false; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._id = wrapper.readInt(); + this._title = wrapper.readString(); + this._badge = wrapper.readString(); + this._colorA = wrapper.readString(); + this._colorB = wrapper.readString(); + this._ownerOrFavorite = wrapper.readBoolean(); + this._ownerId = wrapper.readInt(); + this._hasForum = wrapper.readBoolean(); + + return true; + } + + public get id(): number + { + return this._id; + } + + public get title(): string + { + return this._title; + } + + public get badge(): string + { + return this._badge; + } + + public get colorA(): string + { + return this._colorA; + } + + public get colorB(): string + { + return this._colorB; + } + + public get ownerOrFavorite(): boolean + { + return this._ownerOrFavorite; + } + + public get ownerId(): number + { + return this._ownerId; + } + + public get hasForum(): boolean + { + return this._hasForum; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/group/utils/GroupMemberParser.ts b/src/nitro/communication/messages/parser/group/utils/GroupMemberParser.ts new file mode 100644 index 00000000..3322b685 --- /dev/null +++ b/src/nitro/communication/messages/parser/group/utils/GroupMemberParser.ts @@ -0,0 +1,76 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; + +export class GroupRank +{ + public static readonly OWNER: number = 0; + public static readonly ADMIN: number = 1; + public static readonly MEMBER: number = 2; + public static readonly REQUESTED: number = 3; + public static readonly DELETED: number = 4; +} + +export default class GroupMemberParser +{ + private _rank: number; + private _id: number; + private _name: string; + private _figure: string; + private _joinedAt: string; + + constructor(wrapper: IMessageDataWrapper) + { + if(!wrapper) throw new Error('invalid_wrapper'); + + this.flush(); + this.parse(wrapper); + } + + public flush(): boolean + { + this._rank = -1; + this._id = 0; + this._name = null; + this._figure = null; + this._joinedAt = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._rank = wrapper.readInt(); + this._id = wrapper.readInt(); + this._name = wrapper.readString(); + this._figure = wrapper.readString(); + this._joinedAt = wrapper.readString(); + + return true; + } + + public get id(): number + { + return this._id; + } + + public get name(): string + { + return this._name; + } + + public get figure(): string + { + return this._figure; + } + + public get rank(): number + { + return this._rank; + } + + public get joinedAt(): string + { + return this._joinedAt; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/help/CallForHelpResultMessageParser.ts b/src/nitro/communication/messages/parser/help/CallForHelpResultMessageParser.ts new file mode 100644 index 00000000..98eee1d3 --- /dev/null +++ b/src/nitro/communication/messages/parser/help/CallForHelpResultMessageParser.ts @@ -0,0 +1,36 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; + +export class CallForHelpResultMessageParser implements IMessageParser +{ + private _resultType: number; + private _messageText: string; + + public flush(): boolean + { + this._resultType = 0; + this._messageText = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._resultType = wrapper.readInt(); + this._messageText = wrapper.readString(); + + return true; + } + + public get resultType(): number + { + return this._resultType; + } + + public get messageText(): string + { + return this._messageText; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/inventory/achievements/AchievementParser.ts b/src/nitro/communication/messages/parser/inventory/achievements/AchievementParser.ts new file mode 100644 index 00000000..cd8fa43f --- /dev/null +++ b/src/nitro/communication/messages/parser/inventory/achievements/AchievementParser.ts @@ -0,0 +1,29 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; +import { Achievement } from '../../../incoming/inventory/achievements/Achievement'; + +export class AchievementParser implements IMessageParser +{ + private _achievement: Achievement; + + public flush(): boolean + { + this._achievement = null; + + return true; + } + + public parse(k: IMessageDataWrapper): boolean + { + if(!k) return false; + + this._achievement = new Achievement(k); + + return true; + } + + public get achievement(): Achievement + { + return this._achievement; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/inventory/achievements/AchievementsParser.ts b/src/nitro/communication/messages/parser/inventory/achievements/AchievementsParser.ts new file mode 100644 index 00000000..9e7b081a --- /dev/null +++ b/src/nitro/communication/messages/parser/inventory/achievements/AchievementsParser.ts @@ -0,0 +1,47 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; +import { Achievement } from '../../../incoming/inventory/achievements/Achievement'; + +export class AchievementsParser implements IMessageParser +{ + private _achievements: Achievement[]; + private _Str_19269: string; + + public flush(): boolean + { + this._achievements = []; + this._Str_19269 = null; + + return true; + } + + public parse(k: IMessageDataWrapper): boolean + { + if(!k) return false; + + this._achievements = []; + + let totalCount = k.readInt(); + + while(totalCount > 0) + { + this._achievements.push(new Achievement(k)); + + totalCount--; + } + + this._Str_19269 = k.readString(); + + return true; + } + + public get achievements(): Achievement[] + { + return this._achievements; + } + + public get _Str_16300(): string + { + return this._Str_19269; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/inventory/achievements/AchievementsScoreParser.ts b/src/nitro/communication/messages/parser/inventory/achievements/AchievementsScoreParser.ts new file mode 100644 index 00000000..b816c4c5 --- /dev/null +++ b/src/nitro/communication/messages/parser/inventory/achievements/AchievementsScoreParser.ts @@ -0,0 +1,28 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class AchievementsScoreParser implements IMessageParser +{ + private _score: number; + + public flush(): boolean + { + this._score = 0; + + return true; + } + + public parse(k: IMessageDataWrapper): boolean + { + if(!k) return false; + + this._score = k.readInt(); + + return true; + } + + public get score(): number + { + return this._score; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/inventory/avatareffect/AvatarEffectActivatedParser.ts b/src/nitro/communication/messages/parser/inventory/avatareffect/AvatarEffectActivatedParser.ts new file mode 100644 index 00000000..edd61712 --- /dev/null +++ b/src/nitro/communication/messages/parser/inventory/avatareffect/AvatarEffectActivatedParser.ts @@ -0,0 +1,44 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class AvatarEffectActivatedParser implements IMessageParser +{ + private _type: number; + private _duration: number; + private _isPermanent: boolean; + + public flush(): boolean + { + this._type = 0; + this._duration = 0; + this._isPermanent = false; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._type = wrapper.readInt(); + this._duration = wrapper.readInt(); + this._isPermanent = wrapper.readBoolean(); + + return true; + } + + public get type(): number + { + return this._type; + } + + public get duration(): number + { + return this._duration; + } + + public get isPermanent(): boolean + { + return this._isPermanent; + } +} diff --git a/src/nitro/communication/messages/parser/inventory/avatareffect/AvatarEffectAddedParser.ts b/src/nitro/communication/messages/parser/inventory/avatareffect/AvatarEffectAddedParser.ts new file mode 100644 index 00000000..533aa2d7 --- /dev/null +++ b/src/nitro/communication/messages/parser/inventory/avatareffect/AvatarEffectAddedParser.ts @@ -0,0 +1,52 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class AvatarEffectAddedParser implements IMessageParser +{ + private _type: number; + private _subType: number; + private _duration: number; + private _permanent: boolean; + + public flush(): boolean + { + this._type = 0; + this._subType = 0; + this._duration = 0; + this._permanent = false; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._type = wrapper.readInt(); + this._subType = wrapper.readInt(); + this._duration = wrapper.readInt(); + this._permanent = wrapper.readBoolean(); + + return true; + } + + public get type(): number + { + return this._type; + } + + public get _Str_3882(): number + { + return this._subType; + } + + public get duration(): number + { + return this._duration; + } + + public get _Str_4010(): boolean + { + return this._permanent; + } +} diff --git a/src/nitro/communication/messages/parser/inventory/avatareffect/AvatarEffectExpiredParser.ts b/src/nitro/communication/messages/parser/inventory/avatareffect/AvatarEffectExpiredParser.ts new file mode 100644 index 00000000..0319d0f3 --- /dev/null +++ b/src/nitro/communication/messages/parser/inventory/avatareffect/AvatarEffectExpiredParser.ts @@ -0,0 +1,28 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class AvatarEffectExpiredParser implements IMessageParser +{ + private _type: number; + + public flush(): boolean + { + this._type = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._type = wrapper.readInt(); + + return true; + } + + public get type(): number + { + return this._type; + } +} diff --git a/src/nitro/communication/messages/parser/inventory/avatareffect/AvatarEffectSelectedParser.ts b/src/nitro/communication/messages/parser/inventory/avatareffect/AvatarEffectSelectedParser.ts new file mode 100644 index 00000000..afa0067d --- /dev/null +++ b/src/nitro/communication/messages/parser/inventory/avatareffect/AvatarEffectSelectedParser.ts @@ -0,0 +1,28 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class AvatarEffectSelectedParser implements IMessageParser +{ + private _type: number; + + public flush(): boolean + { + this._type = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._type = wrapper.readInt(); + + return true; + } + + public get type(): number + { + return this._type; + } +} diff --git a/src/nitro/communication/messages/parser/inventory/avatareffect/AvatarEffectsParser.ts b/src/nitro/communication/messages/parser/inventory/avatareffect/AvatarEffectsParser.ts new file mode 100644 index 00000000..bb1475a3 --- /dev/null +++ b/src/nitro/communication/messages/parser/inventory/avatareffect/AvatarEffectsParser.ts @@ -0,0 +1,45 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; +import { AvatarEffect } from '../../../incoming/inventory/avatareffect/AvatarEffect'; + +export class AvatarEffectsParser implements IMessageParser +{ + private _effects: AvatarEffect[]; + + public flush(): boolean + { + this._effects = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + let totalEffects = wrapper.readInt(); + + while(totalEffects > 0) + { + const effect = new AvatarEffect(); + + effect.type = wrapper.readInt(); + effect._Str_3882 = wrapper.readInt(); + effect.duration = wrapper.readInt(); + effect._Str_18572 = wrapper.readInt(); + effect._Str_12185 = wrapper.readInt(); + effect._Str_4010 = wrapper.readBoolean(); + + this._effects.push(effect); + + totalEffects--; + } + + return true; + } + + public get effects(): AvatarEffect[] + { + return this._effects; + } +} diff --git a/src/nitro/communication/messages/parser/inventory/badges/BadgesParser.ts b/src/nitro/communication/messages/parser/inventory/badges/BadgesParser.ts new file mode 100644 index 00000000..5361cc09 --- /dev/null +++ b/src/nitro/communication/messages/parser/inventory/badges/BadgesParser.ts @@ -0,0 +1,71 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; +import { AdvancedMap } from '../../../../../../core/utils/AdvancedMap'; + +export class BadgesParser implements IMessageParser +{ + private _allBadgeCodes: string[]; + private _activeBadgeCodes: string[]; + private _badgeIds: AdvancedMap; + + public flush(): boolean + { + this._allBadgeCodes = []; + this._activeBadgeCodes = []; + this._badgeIds = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._allBadgeCodes = []; + this._activeBadgeCodes = []; + this._badgeIds = new AdvancedMap(); + + let count = wrapper.readInt(); + + while(count > 0) + { + const badgeId = wrapper.readInt(); + const badgeCode = wrapper.readString(); + + this._badgeIds.add(badgeCode, badgeId); + + this._allBadgeCodes.push(badgeCode); + + count--; + } + + count = wrapper.readInt(); + + while(count > 0) + { + const badgeSlot = wrapper.readInt(); + const badgeCode = wrapper.readString(); + + this._activeBadgeCodes[badgeSlot] = badgeCode; + + count--; + } + + return true; + } + + public getBadgeId(k: string): number + { + return this._badgeIds.getValue(k); + } + + public getAllBadgeCodes(): string[] + { + return this._allBadgeCodes; + } + + public getActiveBadgeCodes(): string[] + { + return this._activeBadgeCodes; + } +} diff --git a/src/nitro/communication/messages/parser/inventory/badges/_Str_7305.ts b/src/nitro/communication/messages/parser/inventory/badges/_Str_7305.ts new file mode 100644 index 00000000..c3f977d8 --- /dev/null +++ b/src/nitro/communication/messages/parser/inventory/badges/_Str_7305.ts @@ -0,0 +1,46 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; +import { _Str_7446 } from './_Str_7446'; + +export class _Str_7305 implements IMessageParser +{ + private _data: _Str_7446[]; + + public flush(): boolean + { + this._data = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + let _local_2 = wrapper.readInt(); + + while(_local_2 > 0) + { + const _local_4 = wrapper.readString(); + const _local_5 = wrapper.readInt(); + + let _local_6 = 0; + + while(_local_6 < _local_5) + { + this._data.push(new _Str_7446(_local_4, wrapper)); + + _local_6++; + } + + _local_2--; + } + + return true; + } + + public get data(): _Str_7446[] + { + return this._data; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/inventory/badges/_Str_7446.ts b/src/nitro/communication/messages/parser/inventory/badges/_Str_7446.ts new file mode 100644 index 00000000..775d3382 --- /dev/null +++ b/src/nitro/communication/messages/parser/inventory/badges/_Str_7446.ts @@ -0,0 +1,25 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; + +export class _Str_7446 +{ + private _badgeId: string; + private _limit: number; + + constructor(k: string, _arg_2: IMessageDataWrapper) + { + if(!_arg_2) throw new Error('invalid_parser'); + + this._badgeId = (('ACH_' + k) + _arg_2.readInt()); + this._limit = _arg_2.readInt(); + } + + public get badgeId(): string + { + return this._badgeId; + } + + public get limit(): number + { + return this._limit; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/inventory/badges/_Str_7491.ts b/src/nitro/communication/messages/parser/inventory/badges/_Str_7491.ts new file mode 100644 index 00000000..e6eb6a18 --- /dev/null +++ b/src/nitro/communication/messages/parser/inventory/badges/_Str_7491.ts @@ -0,0 +1,36 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class _Str_7491 implements IMessageParser +{ + private _badgeId: number; + private _Str_2722: string; + + public flush(): boolean + { + this._badgeId = 0; + this._Str_2722 = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._badgeId = wrapper.readInt(); + this._Str_2722 = wrapper.readString(); + + return true; + } + + public get badgeId(): number + { + return this._badgeId; + } + + public get _Str_2494(): string + { + return this._Str_2722; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/inventory/badges/_Str_9135.ts b/src/nitro/communication/messages/parser/inventory/badges/_Str_9135.ts new file mode 100644 index 00000000..29ffa69c --- /dev/null +++ b/src/nitro/communication/messages/parser/inventory/badges/_Str_9135.ts @@ -0,0 +1,33 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class _Str_9135 implements IMessageParser +{ + private _Str_10244: string; + private _Str_22220: boolean; + + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._Str_10244 = wrapper.readString(); + this._Str_22220 = wrapper.readBoolean(); + + return true; + } + + public get _Str_25181(): string + { + return this._Str_10244; + } + + public get _Str_25366(): boolean + { + return this._Str_22220; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/inventory/bots/BotAddedToInventoryParser.ts b/src/nitro/communication/messages/parser/inventory/bots/BotAddedToInventoryParser.ts new file mode 100644 index 00000000..17c62b66 --- /dev/null +++ b/src/nitro/communication/messages/parser/inventory/bots/BotAddedToInventoryParser.ts @@ -0,0 +1,37 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; +import { BotData } from './BotData'; + +export class BotAddedToInventoryParser implements IMessageParser +{ + private _item: BotData; + private _openInventory: boolean; + + public flush(): boolean + { + this._item = null; + this._openInventory = false; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._item = new BotData(wrapper); + this._openInventory = wrapper.readBoolean(); + + return true; + } + + public get item(): BotData + { + return this._item; + } + + public openInventory(): boolean + { + return this._openInventory; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/inventory/bots/BotData.ts b/src/nitro/communication/messages/parser/inventory/bots/BotData.ts new file mode 100644 index 00000000..0c41834c --- /dev/null +++ b/src/nitro/communication/messages/parser/inventory/bots/BotData.ts @@ -0,0 +1,46 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; + +export class BotData +{ + private _id: number; + private _name: string; + private _motto: string; + private _gender: string; + private _figure: string; + + constructor(wrapper: IMessageDataWrapper) + { + if(!wrapper) throw new Error('invalid_parser'); + + this._id = wrapper.readInt(); + this._name = wrapper.readString(); + this._motto = wrapper.readString(); + this._gender = wrapper.readString(); + this._figure = wrapper.readString(); + } + + public get id(): number + { + return this._id; + } + + public get name(): string + { + return this._name; + } + + public get motto(): string + { + return this._motto; + } + + public get figure(): string + { + return this._figure; + } + + public get gender(): string + { + return this._gender; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/inventory/bots/BotInventoryMessageParser.ts b/src/nitro/communication/messages/parser/inventory/bots/BotInventoryMessageParser.ts new file mode 100644 index 00000000..35aff960 --- /dev/null +++ b/src/nitro/communication/messages/parser/inventory/bots/BotInventoryMessageParser.ts @@ -0,0 +1,38 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; +import { BotData } from './BotData'; + +export class BotInventoryMessageParser implements IMessageParser +{ + private _items: Map; + + public flush(): boolean + { + this._items = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + this._items = new Map(); + + let count = wrapper.readInt(); + + while(count > 0) + { + const data = new BotData(wrapper); + + this._items.set(data.id, data); + + count--; + } + + return true; + } + + public get items(): Map + { + return this._items; + } +} diff --git a/src/nitro/communication/messages/parser/inventory/bots/BotReceivedMessageParser.ts b/src/nitro/communication/messages/parser/inventory/bots/BotReceivedMessageParser.ts new file mode 100644 index 00000000..43b2b87d --- /dev/null +++ b/src/nitro/communication/messages/parser/inventory/bots/BotReceivedMessageParser.ts @@ -0,0 +1,37 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; +import { BotData } from './BotData'; + +export class BotInventoryParser implements IMessageParser +{ + private _boughtAsGift: boolean; + private _item: BotData; + + public flush(): boolean + { + this._boughtAsGift = false; + this._item = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._boughtAsGift = wrapper.readBoolean(); + this._item = new BotData(wrapper); + + return true; + } + + public get boughtAsGift(): boolean + { + return this._boughtAsGift; + } + + public get item(): BotData + { + return this._item; + } +} diff --git a/src/nitro/communication/messages/parser/inventory/bots/BotRemovedFromInventoryParser.ts b/src/nitro/communication/messages/parser/inventory/bots/BotRemovedFromInventoryParser.ts new file mode 100644 index 00000000..d93e2c33 --- /dev/null +++ b/src/nitro/communication/messages/parser/inventory/bots/BotRemovedFromInventoryParser.ts @@ -0,0 +1,28 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class BotRemovedFromInventoryParser implements IMessageParser +{ + private _itemId: number; + + public flush(): boolean + { + this._itemId = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._itemId = wrapper.readInt(); + + return true; + } + + public get itemId(): number + { + return this._itemId; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/inventory/clothing/FigureSetIdsMessageParser.ts b/src/nitro/communication/messages/parser/inventory/clothing/FigureSetIdsMessageParser.ts new file mode 100644 index 00000000..8040823d --- /dev/null +++ b/src/nitro/communication/messages/parser/inventory/clothing/FigureSetIdsMessageParser.ts @@ -0,0 +1,51 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class FigureSetIdsMessageParser implements IMessageParser +{ + private _figureSetIds: number[]; + private _boundFurnitureNames: string[] + + public flush(): boolean + { + this._figureSetIds = []; + this._boundFurnitureNames = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + let totalSetIds = wrapper.readInt(); + + while(totalSetIds > 0) + { + this._figureSetIds.push(wrapper.readInt()); + + totalSetIds--; + } + + let totalFurnitureNames = wrapper.readInt(); + + while(totalFurnitureNames > 0) + { + this._boundFurnitureNames.push(wrapper.readString()); + + totalFurnitureNames--; + } + + return true; + } + + public get figureSetIds(): number[] + { + return this._figureSetIds; + } + + public get boundsFurnitureNames(): string[] + { + return this._boundFurnitureNames; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/inventory/clothing/_Str_8728.ts b/src/nitro/communication/messages/parser/inventory/clothing/_Str_8728.ts new file mode 100644 index 00000000..bc668240 --- /dev/null +++ b/src/nitro/communication/messages/parser/inventory/clothing/_Str_8728.ts @@ -0,0 +1,28 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class _Str_8728 implements IMessageParser +{ + private _itemId: number; + + public flush(): boolean + { + this._itemId = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._itemId = wrapper.readInt(); + + return true; + } + + public get itemId(): number + { + return this._itemId; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/inventory/clothing/_Str_9021.ts b/src/nitro/communication/messages/parser/inventory/clothing/_Str_9021.ts new file mode 100644 index 00000000..555769dc --- /dev/null +++ b/src/nitro/communication/messages/parser/inventory/clothing/_Str_9021.ts @@ -0,0 +1,28 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class _Str_9021 implements IMessageParser +{ + private _itemId: number; + + public flush(): boolean + { + this._itemId = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._itemId = wrapper.readInt(); + + return true; + } + + public get itemId(): number + { + return this._itemId; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/inventory/furniture/FurnitureGiftOpenedParser.ts b/src/nitro/communication/messages/parser/inventory/furniture/FurnitureGiftOpenedParser.ts new file mode 100644 index 00000000..2b95cea5 --- /dev/null +++ b/src/nitro/communication/messages/parser/inventory/furniture/FurnitureGiftOpenedParser.ts @@ -0,0 +1,72 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +// see _Str_8104 +export class FurnitureGiftOpenedParser implements IMessageParser +{ + private _Str_2625: string; + private _Str_2825: number; + private _Str_2570: string; + private _Str_3054: number; + private _Str_3970: string; + private _Str_3224: boolean; + private _Str_10229: string; + + public flush(): boolean + { + this._Str_2625 = ''; + this._Str_2825 = 0; + this._Str_2570 = ''; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._Str_2625 = wrapper.readString(); + this._Str_2825 = wrapper.readInt(); + this._Str_2570 = wrapper.readString(); + this._Str_3054 = wrapper.readInt(); + this._Str_3970 = wrapper.readString(); + this._Str_3224 = wrapper.readBoolean(); + this._Str_10229 = wrapper.readString(); + return true; + } + + public get _Str_2887():string + { + return this._Str_2625; + } + + public get classId():number + { + return this._Str_2825; + } + + public get productCode():string + { + return this._Str_2570; + } + + public get placedItemId():number + { + return this._Str_3054; + } + + public get placedItemType():string + { + return this._Str_3970; + } + + public get _Str_4057():boolean + { + return this._Str_3224; + } + + public get petFigureString():string + { + return this._Str_10229; + } +} diff --git a/src/nitro/communication/messages/parser/inventory/furniture/FurnitureListAddOrUpdateParser.ts b/src/nitro/communication/messages/parser/inventory/furniture/FurnitureListAddOrUpdateParser.ts new file mode 100644 index 00000000..5eaadf51 --- /dev/null +++ b/src/nitro/communication/messages/parser/inventory/furniture/FurnitureListAddOrUpdateParser.ts @@ -0,0 +1,29 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; +import { FurnitureListItemParser } from './utils/FurnitureListItemParser'; + +export class FurnitureListAddOrUpdateParser implements IMessageParser +{ + private _items: FurnitureListItemParser[]; + + public flush(): boolean + { + this._items = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._items.push(new FurnitureListItemParser(wrapper)); + + return true; + } + + public get items(): FurnitureListItemParser[] + { + return this._items; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/inventory/furniture/FurnitureListInvalidateParser.ts b/src/nitro/communication/messages/parser/inventory/furniture/FurnitureListInvalidateParser.ts new file mode 100644 index 00000000..d611a3a6 --- /dev/null +++ b/src/nitro/communication/messages/parser/inventory/furniture/FurnitureListInvalidateParser.ts @@ -0,0 +1,17 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class FurnitureListInvalidateParser implements IMessageParser +{ + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + return true; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/inventory/furniture/FurnitureListParser.ts b/src/nitro/communication/messages/parser/inventory/furniture/FurnitureListParser.ts new file mode 100644 index 00000000..edd386ee --- /dev/null +++ b/src/nitro/communication/messages/parser/inventory/furniture/FurnitureListParser.ts @@ -0,0 +1,55 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; +import { FurnitureListItemParser } from './utils/FurnitureListItemParser'; + +export class FurnitureListParser implements IMessageParser +{ + private _totalFragments: number; + private _fragmentNumber: number; + private _fragment: Map; + + public flush(): boolean + { + this._totalFragments = 0; + this._fragmentNumber = 0; + this._fragment = new Map(); + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._totalFragments = wrapper.readInt(); + this._fragmentNumber = wrapper.readInt(); + + let totalItems = wrapper.readInt(); + + while(totalItems > 0) + { + const item = new FurnitureListItemParser(wrapper); + + if(item) this._fragment.set(item.itemId, item); + + totalItems--; + } + + return true; + } + + public get totalFragments(): number + { + return this._totalFragments; + } + + public get fragmentNumber(): number + { + return this._fragmentNumber; + } + + public get fragment(): Map + { + return this._fragment; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/inventory/furniture/FurnitureListRemovedParser.ts b/src/nitro/communication/messages/parser/inventory/furniture/FurnitureListRemovedParser.ts new file mode 100644 index 00000000..3cb66b8e --- /dev/null +++ b/src/nitro/communication/messages/parser/inventory/furniture/FurnitureListRemovedParser.ts @@ -0,0 +1,28 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class FurnitureListRemovedParser implements IMessageParser +{ + private _itemId: number; + + public flush(): boolean + { + this._itemId = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._itemId = wrapper.readInt(); + + return true; + } + + public get itemId(): number + { + return this._itemId; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/inventory/furniture/FurniturePostItPlacedParser.ts b/src/nitro/communication/messages/parser/inventory/furniture/FurniturePostItPlacedParser.ts new file mode 100644 index 00000000..78ea8ac0 --- /dev/null +++ b/src/nitro/communication/messages/parser/inventory/furniture/FurniturePostItPlacedParser.ts @@ -0,0 +1,36 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class FurniturePostItPlacedParser implements IMessageParser +{ + private _itemId: number; + private _itemsLeft: number; + + public flush(): boolean + { + this._itemId = 0; + this._itemsLeft = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._itemId = wrapper.readInt(); + this._itemsLeft = wrapper.readInt(); + + return true; + } + + public get itemId(): number + { + return this._itemId; + } + + public get itemsLeft(): number + { + return this._itemsLeft; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/inventory/furniture/utils/FurnitureListItemParser.ts b/src/nitro/communication/messages/parser/inventory/furniture/utils/FurnitureListItemParser.ts new file mode 100644 index 00000000..ac47d00c --- /dev/null +++ b/src/nitro/communication/messages/parser/inventory/furniture/utils/FurnitureListItemParser.ts @@ -0,0 +1,219 @@ +import { IMessageDataWrapper } from '../../../../../../../core/communication/messages/IMessageDataWrapper'; +import { Nitro } from '../../../../../../Nitro'; +import { IObjectData } from '../../../../../../room/object/data/IObjectData'; +import { IFurnitureItemData } from '../../../../incoming/inventory/furni/IFurnitureItemData'; +import { FurnitureDataParser } from '../../../room/furniture/FurnitureDataParser'; + +export class FurnitureListItemParser implements IFurnitureItemData +{ + private static WALL_ITEM: string = 'I'; + private static FLOOR_ITEM: string = 'S'; + + private _rentable: boolean; + private _itemId: number; + private _furniType: string; + private _ref: number; + private _spriteId: number; + private _category: number; + private _stuffData: IObjectData; + private _isGroupable: boolean; + private _isRecyclable: boolean; + private _tradable: boolean; + private _sellable: boolean; + private _secondsToExpiration: number; + private _Str_3182: number; + private _flatId: number; + private _isWallItem: boolean; + private _hasRentPeriodStarted: boolean; + private _Str_5390: number; + private _slotId: string; + private _Str_2808: number; + + constructor(wrapper: IMessageDataWrapper) + { + if(!wrapper) throw new Error('invalid_wrapper'); + + this.flush(); + this.parse(wrapper); + } + + public flush(): boolean + { + this._rentable = false; + this._itemId = 0; + this._furniType = null; + this._ref = 0; + this._spriteId = 0; + this._category = 0; + this._stuffData = null; + this._isGroupable = false; + this._isRecyclable = false; + this._tradable = false; + this._sellable = false; + this._secondsToExpiration = 0; + this._Str_3182 = 0; + this._flatId = 0; + this._isWallItem = false; + this._hasRentPeriodStarted = false; + this._Str_5390 = 0; + this._slotId = ''; + this._Str_2808 = -1; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._itemId = wrapper.readInt(); + this._furniType = wrapper.readString(); + this._ref = wrapper.readInt(); + this._spriteId = wrapper.readInt(); + this._category = wrapper.readInt(); + this._stuffData = FurnitureDataParser.parseObjectData(wrapper); + this._isRecyclable = wrapper.readBoolean(); + this._tradable = wrapper.readBoolean(); + this._isGroupable = wrapper.readBoolean(); + this._sellable = wrapper.readBoolean(); + this._secondsToExpiration = wrapper.readInt(); + this._Str_5390 = Nitro.instance.time; + + if(this.secondsToExpiration > -1) + { + this._rentable = true; + } + else + { + this._rentable = false; + this._secondsToExpiration = -1; + } + + this._hasRentPeriodStarted = wrapper.readBoolean(); + this._flatId = wrapper.readInt(); + this._isWallItem = (this._furniType === FurnitureListItemParser.WALL_ITEM); + + if(this._furniType === FurnitureListItemParser.FLOOR_ITEM) + { + this._slotId = wrapper.readString(); + this._Str_3182 = wrapper.readInt(); + } + + return true; + } + + public get itemId(): number + { + return this._itemId; + } + + public get furniType(): string + { + return this._furniType; + } + + public get ref(): number + { + return this._ref; + } + + public get spriteId(): number + { + return this._spriteId; + } + + public get category(): number + { + return this._category; + } + + public get stuffData(): IObjectData + { + return this._stuffData; + } + + public get isGroupable(): boolean + { + return this._isGroupable; + } + + public get isRecycleable(): boolean + { + return this._isRecyclable; + } + + public get tradable(): boolean + { + return this._tradable; + } + + public get sellable(): boolean + { + return this._sellable; + } + + public get secondsToExpiration(): number + { + return this._secondsToExpiration; + } + + public get flatId(): number + { + return this._flatId; + } + + public get slotId(): string + { + return this._slotId; + } + + public get _Str_3951(): number + { + return this._Str_2808; + } + + public get _Str_2794(): number + { + return this._Str_3182; + } + + public get rentable(): boolean + { + return this._rentable; + } + + public get isWallItem(): boolean + { + return this._isWallItem; + } + + public get hasRentPeriodStarted(): boolean + { + return this._hasRentPeriodStarted; + } + + public get _Str_10616(): number + { + return this._Str_5390; + } + + public get _Str_8932(): number + { + return 0; + } + + public get _Str_9050(): number + { + return 0; + } + + public get _Str_9408(): number + { + return 0; + } + + public get _Str_19297(): boolean + { + return !(this._furniType.indexOf('external_image') === -1); + } +} diff --git a/src/nitro/communication/messages/parser/inventory/pets/PetAddedToInventoryParser.ts b/src/nitro/communication/messages/parser/inventory/pets/PetAddedToInventoryParser.ts new file mode 100644 index 00000000..26c8e91c --- /dev/null +++ b/src/nitro/communication/messages/parser/inventory/pets/PetAddedToInventoryParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; +import { PetData } from './PetData'; + +export class PetAddedToInventoryParser implements IMessageParser +{ + private _pet: PetData; + private _boughtAsGift: boolean; + + public flush(): boolean + { + this._pet = null; + this._boughtAsGift = false; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + this._pet = new PetData(wrapper); + this._boughtAsGift = wrapper.readBoolean(); + + return true; + } + + public get pet(): PetData + { + return this._pet; + } + + public get boughtAsGift(): boolean + { + return this._boughtAsGift; + } +} diff --git a/src/nitro/communication/messages/parser/inventory/pets/PetBoughtNotificationMessageParser.ts b/src/nitro/communication/messages/parser/inventory/pets/PetBoughtNotificationMessageParser.ts new file mode 100644 index 00000000..f7fdfbce --- /dev/null +++ b/src/nitro/communication/messages/parser/inventory/pets/PetBoughtNotificationMessageParser.ts @@ -0,0 +1,32 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; +import { PetData } from './PetData'; + +export class PetBoughtNotificationMessageParser implements IMessageParser +{ + private _gift: boolean; + private _pet: PetData; + + public flush(): boolean + { + return true; + } + + public parse(k: IMessageDataWrapper): boolean + { + this._gift = k.readBoolean(); + this._pet = new PetData(k); + + return true; + } + + public get gift(): boolean + { + return this._gift; + } + + public get pet(): PetData + { + return this._pet; + } +} diff --git a/src/nitro/communication/messages/parser/inventory/pets/PetData.ts b/src/nitro/communication/messages/parser/inventory/pets/PetData.ts new file mode 100644 index 00000000..0be87f16 --- /dev/null +++ b/src/nitro/communication/messages/parser/inventory/pets/PetData.ts @@ -0,0 +1,70 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { PetFigureData } from './PetFigureData'; + +export class PetData +{ + private _id: number; + private _name: string; + private _figureData: PetFigureData; + private _level: number; + + constructor(wrapper: IMessageDataWrapper) + { + if(!wrapper) throw new Error('invalid_wrapper'); + + this._id = wrapper.readInt(); + this._name = wrapper.readString(); + this._figureData = new PetFigureData(wrapper); + this._level = wrapper.readInt(); + } + + public get id(): number + { + return this._id; + } + + public get name(): string + { + return this._name; + } + + public get typeId(): number + { + return this._figureData.typeId; + } + + public get paletteId(): number + { + return this._figureData.paletteId; + } + + public get color(): string + { + return this._figureData.color; + } + + public get _Str_3343(): number + { + return this._figureData.breedId; + } + + public get _Str_13619(): number + { + return this._figureData.custompartCount; + } + + public get _Str_4217(): string + { + return this._figureData.figuredata; + } + + public get figureData():PetFigureData + { + return this._figureData; + } + + public get level(): number + { + return this._level; + } +} diff --git a/src/nitro/communication/messages/parser/inventory/pets/PetFigureData.ts b/src/nitro/communication/messages/parser/inventory/pets/PetFigureData.ts new file mode 100644 index 00000000..76233e9a --- /dev/null +++ b/src/nitro/communication/messages/parser/inventory/pets/PetFigureData.ts @@ -0,0 +1,73 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; + +export class PetFigureData +{ + private _typeId: number; + private _paletteId: number; + private _color: string; + private _breedId: number; + private _customPartCount: number; + private _customParts: number[]; + + constructor(wrapper: IMessageDataWrapper) + { + this._typeId = wrapper.readInt(); + this._paletteId = wrapper.readInt(); + this._color = wrapper.readString(); + this._breedId = wrapper.readInt(); + this._customParts = []; + this._customPartCount = wrapper.readInt(); + + let i = 0; + + while(i < this._customPartCount) + { + this._customParts.push(wrapper.readInt()); + this._customParts.push(wrapper.readInt()); + this._customParts.push(wrapper.readInt()); + + i++; + } + } + + public get typeId(): number + { + return this._typeId; + } + + public get paletteId(): number + { + return this._paletteId; + } + + public get color(): string + { + return this._color; + } + + public get breedId(): number + { + return this._breedId; + } + + public get figuredata(): string + { + let figure = ((((this.typeId + ' ') + this.paletteId) + ' ') + this.color); + + figure = (figure + (' ' + this.custompartCount)); + + for(const _local_2 of this.customParts) figure = (figure + (' ' + _local_2)); + + return figure; + } + + public get customParts(): number[] + { + return this._customParts; + } + + public get custompartCount(): number + { + return this._customPartCount; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/inventory/pets/PetInventoryParser.ts b/src/nitro/communication/messages/parser/inventory/pets/PetInventoryParser.ts new file mode 100644 index 00000000..f1a45ed4 --- /dev/null +++ b/src/nitro/communication/messages/parser/inventory/pets/PetInventoryParser.ts @@ -0,0 +1,53 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; +import { PetData } from './PetData'; + +export class PetInventoryParser implements IMessageParser +{ + protected _totalFragments: number; + protected _fragmentNumber: number; + private _fragment: Map; + + public flush(): boolean + { + this._fragment = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + this._totalFragments = wrapper.readInt(); + this._fragmentNumber = wrapper.readInt(); + + let totalCount: number = wrapper.readInt(); + + this._fragment = new Map(); + + while(totalCount > 0) + { + const petData = new PetData(wrapper); + + this._fragment.set(petData.id, petData); + + totalCount--; + } + + return true; + } + + public get totalFragments(): number + { + return this._totalFragments; + } + + public get fragmentNumber(): number + { + return this._fragmentNumber; + } + + public get fragment(): Map + { + return this._fragment; + } +} diff --git a/src/nitro/communication/messages/parser/inventory/pets/PetRemovedFromInventoryParser.ts b/src/nitro/communication/messages/parser/inventory/pets/PetRemovedFromInventoryParser.ts new file mode 100644 index 00000000..f00ec59f --- /dev/null +++ b/src/nitro/communication/messages/parser/inventory/pets/PetRemovedFromInventoryParser.ts @@ -0,0 +1,26 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class PetRemovedFromInventoryParser implements IMessageParser +{ + private _petId: number; + + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._petId = wrapper.readInt(); + + return true; + } + + public get petId(): number + { + return this._petId; + } +} diff --git a/src/nitro/communication/messages/parser/inventory/pets/_Str_6256.ts b/src/nitro/communication/messages/parser/inventory/pets/_Str_6256.ts new file mode 100644 index 00000000..effbdcc5 --- /dev/null +++ b/src/nitro/communication/messages/parser/inventory/pets/_Str_6256.ts @@ -0,0 +1,36 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class _Str_6256 implements IMessageParser +{ + private _Str_6143: number; + private _result: number; + + public flush(): boolean + { + this._Str_6143 = 0; + this._result = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._Str_6143 = wrapper.readInt(); + this._result = wrapper.readInt(); + + return true; + } + + public get _Str_12769(): number + { + return this._Str_6143; + } + + public get result(): number + { + return this._result; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/inventory/pets/_Str_6719.ts b/src/nitro/communication/messages/parser/inventory/pets/_Str_6719.ts new file mode 100644 index 00000000..7dc784a3 --- /dev/null +++ b/src/nitro/communication/messages/parser/inventory/pets/_Str_6719.ts @@ -0,0 +1,83 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; +import { _Str_3763 } from '../../../incoming/room/pet/_Str_3763'; +import { _Str_5753 } from '../../../incoming/room/pet/_Str_5753'; + +export class _Str_6719 implements IMessageParser +{ + private _Str_5743: number; + private _pet1: _Str_3763; + private _pet2: _Str_3763; + private _Str_4447: _Str_5753[]; + private _Str_21973: number; + + public flush(): boolean + { + this._Str_5743 = 0; + + if(this._pet1) + { + this._pet1.dispose(); + this._pet1 = null; + } + + if(this._pet2) + { + this._pet2.dispose(); + this._pet2 = null; + } + + for(const k of this._Str_4447) k && k.dispose(); + + this._Str_4447 = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._Str_5743 = wrapper.readInt(); + this._pet1 = new _Str_3763(wrapper); + this._pet2 = new _Str_3763(wrapper); + + let totalCount = wrapper.readInt(); + + while(totalCount > 0) + { + this._Str_4447.push(new _Str_5753(wrapper)); + + totalCount--; + } + + this._Str_21973 = wrapper.readInt(); + + return true; + } + + public get _Str_12369(): number + { + return this._Str_5743; + } + + public get pet1():_Str_3763 + { + return this._pet1; + } + + public get pet2():_Str_3763 + { + return this._pet2; + } + + public get _Str_10346(): _Str_5753[] + { + return this._Str_4447; + } + + public get _Str_24905(): number + { + return this._Str_21973; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/inventory/pets/_Str_7486.ts b/src/nitro/communication/messages/parser/inventory/pets/_Str_7486.ts new file mode 100644 index 00000000..4a8091b9 --- /dev/null +++ b/src/nitro/communication/messages/parser/inventory/pets/_Str_7486.ts @@ -0,0 +1,26 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class _Str_7486 implements IMessageParser +{ + public static _Str_17785: number = 6; + + private _reason: number; + + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + this._reason = wrapper.readInt(); + + return true; + } + + public get reason(): number + { + return this._reason; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/inventory/pets/_Str_7523.ts b/src/nitro/communication/messages/parser/inventory/pets/_Str_7523.ts new file mode 100644 index 00000000..8d3c0fa6 --- /dev/null +++ b/src/nitro/communication/messages/parser/inventory/pets/_Str_7523.ts @@ -0,0 +1,48 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class _Str_7523 implements IMessageParser +{ + public static _Str_8664: number = 1; + public static _Str_9186: number = 2; + public static _Str_22195: number = 3; + + private _state: number; + private _Str_6614: number; + private _Str_6649: number; + + public flush(): boolean + { + this._state = 0; + this._Str_6614 = 0; + this._Str_6649 = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._state = wrapper.readInt(); + this._Str_6614 = wrapper.readInt(); + this._Str_6649 = wrapper.readInt(); + + return true; + } + + public get state(): number + { + return this._state; + } + + public get _Str_7440(): number + { + return this._Str_6614; + } + + public get _Str_7663(): number + { + return this._Str_6649; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/inventory/pets/_Str_9220.ts b/src/nitro/communication/messages/parser/inventory/pets/_Str_9220.ts new file mode 100644 index 00000000..611c28c9 --- /dev/null +++ b/src/nitro/communication/messages/parser/inventory/pets/_Str_9220.ts @@ -0,0 +1,34 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class _Str_9220 implements IMessageParser +{ + private _Str_5792: number; + private _Str_2388: number; + + public flush(): boolean + { + this._Str_2388 = -1; + this._Str_5792 = -1; + + return true; + } + + public parse(k: IMessageDataWrapper): boolean + { + this._Str_2388 = k.readInt(); + this._Str_5792 = k.readInt(); + + return true; + } + + public get _Str_16731(): number + { + return this._Str_5792; + } + + public get _Str_2508(): number + { + return this._Str_2388; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/inventory/purse/UserCreditsMessageParser.ts b/src/nitro/communication/messages/parser/inventory/purse/UserCreditsMessageParser.ts new file mode 100644 index 00000000..ea0ef61a --- /dev/null +++ b/src/nitro/communication/messages/parser/inventory/purse/UserCreditsMessageParser.ts @@ -0,0 +1,26 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class UserCreditsMessageParser implements IMessageParser +{ + private _balance: number; + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._balance = parseFloat(wrapper.readString()); + + return true; + } + + public flush(): boolean + { + return true; + } + + public get balance(): number + { + return this._balance; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/inventory/trading/TradingAcceptParser.ts b/src/nitro/communication/messages/parser/inventory/trading/TradingAcceptParser.ts new file mode 100644 index 00000000..bbd24e58 --- /dev/null +++ b/src/nitro/communication/messages/parser/inventory/trading/TradingAcceptParser.ts @@ -0,0 +1,36 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class TradingAcceptParser implements IMessageParser +{ + private _userID: number; + private _userAccepts: boolean; + + public flush(): boolean + { + this._userID = -1; + this._userAccepts = false; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._userID = wrapper.readInt(); + this._userAccepts = (wrapper.readInt() > 0); + + return true; + } + + public get _Str_4963(): number + { + return this._userID; + } + + public get _Str_15794(): boolean + { + return this._userAccepts; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/inventory/trading/TradingCloseParser.ts b/src/nitro/communication/messages/parser/inventory/trading/TradingCloseParser.ts new file mode 100644 index 00000000..7ca2c836 --- /dev/null +++ b/src/nitro/communication/messages/parser/inventory/trading/TradingCloseParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class TradingCloseParser implements IMessageParser +{ + public static _Str_16410: number = 1; + + private _userId: number; + private _reason: number; + + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._userId = wrapper.readInt(); + this._reason = wrapper.readInt(); + + return true; + } + + public get _Str_4963(): number + { + return this._userId; + } + + public get reason(): number + { + return this._reason; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/inventory/trading/TradingCompletedParser.ts b/src/nitro/communication/messages/parser/inventory/trading/TradingCompletedParser.ts new file mode 100644 index 00000000..21e5cbe3 --- /dev/null +++ b/src/nitro/communication/messages/parser/inventory/trading/TradingCompletedParser.ts @@ -0,0 +1,17 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class TradingCompletedParser implements IMessageParser +{ + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + return true; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/inventory/trading/TradingConfirmationParser.ts b/src/nitro/communication/messages/parser/inventory/trading/TradingConfirmationParser.ts new file mode 100644 index 00000000..957141a7 --- /dev/null +++ b/src/nitro/communication/messages/parser/inventory/trading/TradingConfirmationParser.ts @@ -0,0 +1,17 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class TradingConfirmationParser implements IMessageParser +{ + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + return true; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/inventory/trading/TradingListItemParser.ts b/src/nitro/communication/messages/parser/inventory/trading/TradingListItemParser.ts new file mode 100644 index 00000000..88897ae0 --- /dev/null +++ b/src/nitro/communication/messages/parser/inventory/trading/TradingListItemParser.ts @@ -0,0 +1,106 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; +import { TradingListItem } from '../../../incoming/inventory/trading/TradingListItem'; + +export class TradingListItemParser implements IMessageParser +{ + private _firstUserID: number; + private _firstUserItemArray: TradingListItem[]; + private _firstUserNumItems: number; + private _firstUserNumCredits: number; + private _secondUserID: number; + private _secondUserItemArray: TradingListItem[]; + private _secondUserNumItems: number; + private _secondUserNumCredits: number; + + public flush(): boolean + { + this._firstUserID = -1; + this._firstUserItemArray = null; + this._firstUserNumItems = 0; + this._firstUserNumCredits = 0; + this._secondUserID = -1; + this._secondUserItemArray = null; + this._secondUserNumItems = 0; + this._secondUserNumCredits = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._firstUserID = wrapper.readInt(); + this._firstUserItemArray = []; + + if(!this.parseItems(wrapper, this._firstUserItemArray)) return false; + + this._firstUserNumItems = wrapper.readInt(); + this._firstUserNumCredits = wrapper.readInt(); + + this._secondUserID = wrapper.readInt(); + this._secondUserItemArray = []; + + if(!this.parseItems(wrapper, this._secondUserItemArray)) return false; + + this._secondUserNumItems = wrapper.readInt(); + this._secondUserNumCredits = wrapper.readInt(); + + return true; + } + + private parseItems(k: IMessageDataWrapper, itemArray: TradingListItem[]): boolean + { + let count = k.readInt(); + + while(count > 0) + { + itemArray.push(new TradingListItem(k)); + + count--; + } + + return true; + } + + public get _Str_15162(): number + { + return this._firstUserID; + } + + public get _Str_17841(): TradingListItem[] + { + return this._firstUserItemArray; + } + + public get _Str_14946(): number + { + return this._firstUserNumItems; + } + + public get _Str_15709(): number + { + return this._firstUserNumCredits; + } + + public get _Str_18215(): number + { + return this._secondUserID; + } + + public get _Str_17465(): TradingListItem[] + { + return this._secondUserItemArray; + } + + public get _Str_13801(): number + { + return this._secondUserNumItems; + } + + public get _Str_9138(): number + { + return this._secondUserNumCredits; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/inventory/trading/TradingNotOpenParser.ts b/src/nitro/communication/messages/parser/inventory/trading/TradingNotOpenParser.ts new file mode 100644 index 00000000..f389a765 --- /dev/null +++ b/src/nitro/communication/messages/parser/inventory/trading/TradingNotOpenParser.ts @@ -0,0 +1,17 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class TradingNotOpenParser implements IMessageParser +{ + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + return true; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/inventory/trading/TradingOpenFailedParser.ts b/src/nitro/communication/messages/parser/inventory/trading/TradingOpenFailedParser.ts new file mode 100644 index 00000000..2f9950a8 --- /dev/null +++ b/src/nitro/communication/messages/parser/inventory/trading/TradingOpenFailedParser.ts @@ -0,0 +1,36 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class TradingOpenFailedParser implements IMessageParser +{ + public static _Str_18150: number = 7; + public static _Str_18383: number = 8; + + private _reason: number; + private _Str_10068: string; + + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._reason = wrapper.readInt(); + this._Str_10068 = wrapper.readString(); + + return true; + } + + public get reason(): number + { + return this._reason; + } + + public get _Str_17035(): string + { + return this._Str_10068; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/inventory/trading/TradingOpenParser.ts b/src/nitro/communication/messages/parser/inventory/trading/TradingOpenParser.ts new file mode 100644 index 00000000..37b318d3 --- /dev/null +++ b/src/nitro/communication/messages/parser/inventory/trading/TradingOpenParser.ts @@ -0,0 +1,52 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class TradingOpenParser implements IMessageParser +{ + private _userId: number; + private _userCanTrade: boolean; + private _otherUserId: number; + private _otherUserCanTrade: boolean; + + public flush(): boolean + { + this._userId = -1; + this._userCanTrade = false; + this._otherUserId = -1; + this._otherUserCanTrade = false; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._userId = wrapper.readInt(); + this._userCanTrade = (wrapper.readInt() === 1); + this._otherUserId = wrapper.readInt(); + this._otherUserCanTrade = (wrapper.readInt() === 1); + + return true; + } + + public get _Str_4963(): number + { + return this._userId; + } + + public get _Str_16764(): boolean + { + return this._userCanTrade; + } + + public get _Str_17613(): number + { + return this._otherUserId; + } + + public get _Str_13374(): boolean + { + return this._otherUserCanTrade; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/inventory/trading/TradingOtherNotAllowedParser.ts b/src/nitro/communication/messages/parser/inventory/trading/TradingOtherNotAllowedParser.ts new file mode 100644 index 00000000..e94a939f --- /dev/null +++ b/src/nitro/communication/messages/parser/inventory/trading/TradingOtherNotAllowedParser.ts @@ -0,0 +1,17 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class TradingOtherNotAllowedParser implements IMessageParser +{ + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + return true; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/inventory/trading/TradingYouAreNotAllowedParser.ts b/src/nitro/communication/messages/parser/inventory/trading/TradingYouAreNotAllowedParser.ts new file mode 100644 index 00000000..d9c83f1e --- /dev/null +++ b/src/nitro/communication/messages/parser/inventory/trading/TradingYouAreNotAllowedParser.ts @@ -0,0 +1,17 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class TradingYouAreNotAllowedParser implements IMessageParser +{ + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + return true; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/moderation/ModeratorMessageParser.ts b/src/nitro/communication/messages/parser/moderation/ModeratorMessageParser.ts new file mode 100644 index 00000000..aee4a095 --- /dev/null +++ b/src/nitro/communication/messages/parser/moderation/ModeratorMessageParser.ts @@ -0,0 +1,36 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; + +export class ModeratorMessageParser implements IMessageParser +{ + private _message: string; + private _link: string; + + public flush(): boolean + { + this._message = null; + this._link = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._message = wrapper.readString(); + this._link = wrapper.readString(); + + return true; + } + + public get message(): string + { + return this._message; + } + + public get link(): string + { + return this._link; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/modtool/ModtoolCFHTopicsParser.ts b/src/nitro/communication/messages/parser/modtool/ModtoolCFHTopicsParser.ts new file mode 100644 index 00000000..d5a4a6c1 --- /dev/null +++ b/src/nitro/communication/messages/parser/modtool/ModtoolCFHTopicsParser.ts @@ -0,0 +1,31 @@ +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { CallForHelpCategoryData } from './utils/CallForHelpCategoryData'; + +export class ModtoolCFHTopicsParser implements IMessageParser +{ + private _callForHelpCategories: CallForHelpCategoryData[]; + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + this._callForHelpCategories = []; + const count = wrapper.readInt(); + let i = 0; + while(i < count) + { + this._callForHelpCategories.push(new CallForHelpCategoryData(wrapper)); + i++; + } + + return true; + } + + public get callForHelpCategories(): CallForHelpCategoryData[] + { + return this._callForHelpCategories; + } +} diff --git a/src/nitro/communication/messages/parser/modtool/ModtoolMainParser.ts b/src/nitro/communication/messages/parser/modtool/ModtoolMainParser.ts new file mode 100644 index 00000000..9d744542 --- /dev/null +++ b/src/nitro/communication/messages/parser/modtool/ModtoolMainParser.ts @@ -0,0 +1,25 @@ +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { CallForHelpCategoryData } from './utils/CallForHelpCategoryData'; +import { _Str_5018 } from './utils/_Str_5018'; + +export class ModtoolMainParser implements IMessageParser +{ + private _data: _Str_5018 = null; + public flush(): boolean + { + this._data = null; + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + this._data = new _Str_5018(wrapper); + return true; + } + + public get data(): _Str_5018 + { + return this._data; + } +} diff --git a/src/nitro/communication/messages/parser/modtool/ModtoolRoomChatlogParser.ts b/src/nitro/communication/messages/parser/modtool/ModtoolRoomChatlogParser.ts new file mode 100644 index 00000000..8c7bbee4 --- /dev/null +++ b/src/nitro/communication/messages/parser/modtool/ModtoolRoomChatlogParser.ts @@ -0,0 +1,64 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; +import { ModtoolRoomChatlogLine } from './utils/ModtoolRoomChatlogLine'; + +export class ModtoolRoomChatlogParser implements IMessageParser +{ + private _id: number; + private _name: string; + private _chatlogCount: number; + private _chatlogs: ModtoolRoomChatlogLine[] = []; + + public flush(): boolean + { + this._id = null; + this._name = null; + this._chatlogCount = 0; + this._chatlogs = []; + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + wrapper.readByte(); + wrapper.readShort(); + wrapper.readString(); + wrapper.readByte(); + this._name = wrapper.readString(); + wrapper.readString(); + wrapper.readByte(); + this._id = wrapper.readInt(); + this._chatlogCount = wrapper.readShort(); + + for(let i = 0; i < this._chatlogCount; i++) + { + const timestamp = wrapper.readString(); + const habboId = wrapper.readInt(); + const username = wrapper.readString(); + const message = wrapper.readString(); + const boolean = wrapper.readBoolean(); + + this._chatlogs.push(new ModtoolRoomChatlogLine(timestamp, habboId, username, message, boolean)); + } + + return true; + } + + public get id(): number + { + return this._id; + } + + public get name(): string + { + return this._name; + } + + public get chatlogs(): ModtoolRoomChatlogLine[] + { + return this._chatlogs; + } + +} diff --git a/src/nitro/communication/messages/parser/modtool/ModtoolRoomInfoParser.ts b/src/nitro/communication/messages/parser/modtool/ModtoolRoomInfoParser.ts new file mode 100644 index 00000000..b710e0d3 --- /dev/null +++ b/src/nitro/communication/messages/parser/modtool/ModtoolRoomInfoParser.ts @@ -0,0 +1,74 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; + +export class ModtoolRoomInfoParser implements IMessageParser +{ + private _id: number; + private _playerAmount: number; + private _owner: boolean; + private _ownerId: number; + private _ownerName: string; + private _bool: boolean; + private _name: string; + private _description: string; + private _tagsTotal: number; + + public flush(): boolean + { + this._id = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._id = wrapper.readInt(); + this._playerAmount = wrapper.readInt(); + this._owner = wrapper.readBoolean(); + this._ownerId = wrapper.readInt(); + this._ownerName = wrapper.readString(); + this._bool = wrapper.readBoolean(); + this._name = wrapper.readString(); + this._description = wrapper.readString(); + this._tagsTotal = wrapper.readInt(); + + return true; + } + + public get id(): number + { + return this._id; + } + + public get playerAmount(): number + { + return this._playerAmount; + } + + public get owner(): boolean + { + return this._owner; + } + + public get ownerId(): number + { + return this._ownerId; + } + + public get ownerName(): string + { + return this._ownerName; + } + + public get name(): string + { + return this._name; + } + + public get description(): string + { + return this._description; + } +} diff --git a/src/nitro/communication/messages/parser/modtool/ModtoolRoomUsersParser.ts b/src/nitro/communication/messages/parser/modtool/ModtoolRoomUsersParser.ts new file mode 100644 index 00000000..5003752b --- /dev/null +++ b/src/nitro/communication/messages/parser/modtool/ModtoolRoomUsersParser.ts @@ -0,0 +1,24 @@ +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { CallForHelpCategoryData } from './utils/CallForHelpCategoryData'; +import { ModtoolRoomVisitedData } from './utils/ModtoolRoomVisitedData'; + +export class ModtoolRoomUsersParser implements IMessageParser +{ + private _data: ModtoolRoomVisitedData; + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + this._data = new ModtoolRoomVisitedData(wrapper); + return true; + } + + public get data(): ModtoolRoomVisitedData + { + return this._data; + } +} diff --git a/src/nitro/communication/messages/parser/modtool/ModtoolUserChatlogParser.ts b/src/nitro/communication/messages/parser/modtool/ModtoolUserChatlogParser.ts new file mode 100644 index 00000000..c8acd0bf --- /dev/null +++ b/src/nitro/communication/messages/parser/modtool/ModtoolUserChatlogParser.ts @@ -0,0 +1,76 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; +import { ModtoolUserChatlogParserVisit } from './utils/ModtoolUserChatlogParserVisit'; +import { ModtoolUserChatlogParserChatlog } from './utils/ModtoolUserChatlogParserChatlog'; + +export class ModtoolUserChatlogParser implements IMessageParser +{ + private _id: number; + private _username: string; + private _size: number; + private _roomVisits: ModtoolUserChatlogParserVisit[] = []; + + public flush(): boolean + { + this._id = null; + this._username = null; + this._size = null; + this._roomVisits = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._id = wrapper.readInt(); + this._username = wrapper.readString(); + this._size = wrapper.readInt(); + for(let i = 0; i < this._size; i++) + { + wrapper.readByte(); + wrapper.readShort(); + wrapper.readString(); + wrapper.readByte(); + const roomName = wrapper.readString(); + wrapper.readString(); + wrapper.readByte(); + const roomId = wrapper.readInt(); + + const chatlogs = []; + + const chatlogSize = wrapper.readShort(); + + for(let i = 0; i < chatlogSize; i++) + { + const timestamp = wrapper.readString(); + const userId = wrapper.readInt(); + const userName = wrapper.readString(); + const message = wrapper.readString(); + const bool = wrapper.readBoolean(); + chatlogs.push(new ModtoolUserChatlogParserChatlog(timestamp, userId, userName, message, bool)); + } + + this._roomVisits.push(new ModtoolUserChatlogParserVisit(roomName, roomId, chatlogs)); + } + + return true; + } + + public get id(): number + { + return this._id; + } + + public get username(): string + { + return this._username; + } + + public get roomVisits(): ModtoolUserChatlogParserVisit[] + { + return this._roomVisits; + } + +} diff --git a/src/nitro/communication/messages/parser/modtool/ModtoolUserInfoParser.ts b/src/nitro/communication/messages/parser/modtool/ModtoolUserInfoParser.ts new file mode 100644 index 00000000..b0ec5ddd --- /dev/null +++ b/src/nitro/communication/messages/parser/modtool/ModtoolUserInfoParser.ts @@ -0,0 +1,34 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; +import { ModtoolUserChatlogParserVisit } from './utils/ModtoolUserChatlogParserVisit'; +import { ModtoolUserChatlogParserChatlog } from './utils/ModtoolUserChatlogParserChatlog'; +import { _Str_5467 } from './utils/_Str_5467'; + +export class ModtoolUserInfoParser implements IMessageParser +{ + private _data: _Str_5467; + + public flush(): boolean + { + this._data = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._data = new _Str_5467(wrapper); + + return true; + } + + public get data(): _Str_5467 + { + return this._data; + } + + + +} diff --git a/src/nitro/communication/messages/parser/modtool/utils/CallForHelpCategoryData.ts b/src/nitro/communication/messages/parser/modtool/utils/CallForHelpCategoryData.ts new file mode 100644 index 00000000..ae233ce3 --- /dev/null +++ b/src/nitro/communication/messages/parser/modtool/utils/CallForHelpCategoryData.ts @@ -0,0 +1,39 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; + +export class CallForHelpCategoryData +{ + private _name: string; + private _topics: _Str_3509[]; + + constructor(wrapper: IMessageDataWrapper) + { + this._topics = []; + this._name = wrapper.readString(); + const count = wrapper.readInt(); + let i = 0; + while(i < count) + { + const name = wrapper.readString(); + const id = wrapper.readInt(); + const unknown = wrapper.readString(); + this._topics.push({ + name, + id, + _Str_18308: unknown + }); + i++; + } + + } + + public get topics(): _Str_3509[] + { + return this._topics; + } +} + +interface _Str_3509 { + name: string; + id: number; + _Str_18308: string; +} diff --git a/src/nitro/communication/messages/parser/modtool/utils/IChatlog.ts b/src/nitro/communication/messages/parser/modtool/utils/IChatlog.ts new file mode 100644 index 00000000..d14b401b --- /dev/null +++ b/src/nitro/communication/messages/parser/modtool/utils/IChatlog.ts @@ -0,0 +1,7 @@ +export interface IChatlog +{ + timestamp: string; + userId: number; + userName: string; + message: string; +} diff --git a/src/nitro/communication/messages/parser/modtool/utils/ModtoolRoomChatlogLine.ts b/src/nitro/communication/messages/parser/modtool/utils/ModtoolRoomChatlogLine.ts new file mode 100644 index 00000000..8a52900a --- /dev/null +++ b/src/nitro/communication/messages/parser/modtool/utils/ModtoolRoomChatlogLine.ts @@ -0,0 +1,39 @@ +import { IChatlog } from './IChatlog'; + +export class ModtoolRoomChatlogLine implements IChatlog +{ + private readonly _timestamp: string; + private readonly _habboId: number; + private readonly _username: string; + private readonly _message: string; + private _boolean: boolean; + + constructor(timestamp: string, habboId: number, username: string, message: string, boolean: boolean) + { + this._timestamp = timestamp; + this._habboId = habboId; + this._username = username; + this._message = message; + this._boolean = boolean; + } + + public get timestamp(): string + { + return this._timestamp; + } + + public get userId(): number + { + return this._habboId; + } + + public get userName(): string + { + return this._username; + } + + public get message(): string + { + return this._message; + } +} diff --git a/src/nitro/communication/messages/parser/modtool/utils/ModtoolRoomVisitedData.ts b/src/nitro/communication/messages/parser/modtool/utils/ModtoolRoomVisitedData.ts new file mode 100644 index 00000000..a86fe581 --- /dev/null +++ b/src/nitro/communication/messages/parser/modtool/utils/ModtoolRoomVisitedData.ts @@ -0,0 +1,39 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { ModtoolUserVisitedRoomsRoom } from './ModtoolUserVisitedRoomsRoom'; + + +export class ModtoolRoomVisitedData +{ + private _userId:number; + private _userName:string; + private _rooms:ModtoolUserVisitedRoomsRoom[]; + + constructor(k:IMessageDataWrapper) + { + this._rooms = []; + this._userId = k.readInt(); + this._userName = k.readString(); + const _local_2 = k.readInt(); + let _local_3 = 0; + while(_local_3 < _local_2) + { + this._rooms.push(new ModtoolUserVisitedRoomsRoom(k)); + _local_3++; + } + } + + public get userId():number + { + return this._userId; + } + + public get userName():string + { + return this._userName; + } + + public get rooms():ModtoolUserVisitedRoomsRoom[] + { + return this._rooms; + } +} diff --git a/src/nitro/communication/messages/parser/modtool/utils/ModtoolUserChatlogParserChatlog.ts b/src/nitro/communication/messages/parser/modtool/utils/ModtoolUserChatlogParserChatlog.ts new file mode 100644 index 00000000..30e450d9 --- /dev/null +++ b/src/nitro/communication/messages/parser/modtool/utils/ModtoolUserChatlogParserChatlog.ts @@ -0,0 +1,44 @@ +import { IChatlog } from './IChatlog'; + +export class ModtoolUserChatlogParserChatlog implements IChatlog +{ + private readonly _timestamp: string; + private readonly _userId: number; + private readonly _userName: string; + private readonly _message: string; + private readonly _bool: boolean; + + constructor(timestamp: string, userId: number, userName: string, message: string, bool: boolean) + { + this._timestamp = timestamp; + this._userId = userId; + this._userName = userName; + this._message = message; + this._bool = bool; + } + + public get timestamp(): string + { + return this._timestamp; + } + + public get userId(): number + { + return this._userId; + } + + public get userName(): string + { + return this._userName; + } + + public get message(): string + { + return this._message; + } + + public get bool(): boolean + { + return this._bool; + } +} diff --git a/src/nitro/communication/messages/parser/modtool/utils/ModtoolUserChatlogParserVisit.ts b/src/nitro/communication/messages/parser/modtool/utils/ModtoolUserChatlogParserVisit.ts new file mode 100644 index 00000000..0b684a85 --- /dev/null +++ b/src/nitro/communication/messages/parser/modtool/utils/ModtoolUserChatlogParserVisit.ts @@ -0,0 +1,31 @@ +import { ModtoolUserChatlogParserChatlog } from './ModtoolUserChatlogParserChatlog'; +import { IChatlog } from './IChatlog'; + +export class ModtoolUserChatlogParserVisit +{ + private readonly _roomName: string; + private readonly _roomId: number; + private readonly _chatlogs: IChatlog[]; + + constructor(roomName: string, roomId: number, chatlogs: IChatlog[]) + { + this._roomName = roomName; + this._roomId = roomId; + this._chatlogs = chatlogs; + } + + public get roomName(): string + { + return this._roomName; + } + + public get roomId(): number + { + return this._roomId; + } + + public get chatlogs(): IChatlog[] + { + return this._chatlogs; + } +} diff --git a/src/nitro/communication/messages/parser/modtool/utils/ModtoolUserVisitedRoomsRoom.ts b/src/nitro/communication/messages/parser/modtool/utils/ModtoolUserVisitedRoomsRoom.ts new file mode 100644 index 00000000..7c9d7a59 --- /dev/null +++ b/src/nitro/communication/messages/parser/modtool/utils/ModtoolUserVisitedRoomsRoom.ts @@ -0,0 +1,37 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; + +export class ModtoolUserVisitedRoomsRoom +{ + private _roomId:number; + private _roomName:string; + private _Str_20266:number; + private _Str_20472:number; + + constructor(k:IMessageDataWrapper) + { + this._roomId = k.readInt(); + this._roomName = k.readString(); + this._Str_20266 = k.readInt(); + this._Str_20472 = k.readInt(); + } + + public get roomId():number + { + return this._roomId; + } + + public get roomName():string + { + return this._roomName; + } + + public get _Str_22929():number + { + return this._Str_20266; + } + + public get _Str_25550():number + { + return this._Str_20472; + } +} diff --git a/src/nitro/communication/messages/parser/modtool/utils/_Str_2484.ts b/src/nitro/communication/messages/parser/modtool/utils/_Str_2484.ts new file mode 100644 index 00000000..3fa44fd8 --- /dev/null +++ b/src/nitro/communication/messages/parser/modtool/utils/_Str_2484.ts @@ -0,0 +1,159 @@ +import { _Str_8176 } from './_Str_8176'; + +export class _Str_2484 +{ + public static _Str_5035: number = 1; + public static _Str_8056: number = 2; + public static _Str_17136: number = 3; + + private _Str_6036: number; + private _state: number; + private _Str_2629: number; + private _Str_21044: number; + private _issueAgeInMilliseconds: number; + private _priority: number; + private _Str_9559: number; + private _Str_21130: number; + private _Str_19722: string; + private _Str_2797: number; + private _Str_5502: string; + private _Str_9859: number; + private _Str_21393: string; + private _message: string; + private _Str_10679: number; + private _Str_15205: _Str_8176[]; + private _disposed: boolean = false; + private _Str_19084: number; + + constructor(k: number, _arg_2: number, _arg_3: number, _arg_4: number, _arg_5: number, _arg_6: number, _arg_7: number, _arg_8: number, _arg_9: string, _arg_10: number, _arg_11: string, _arg_12: number, _arg_13: string, _arg_14: string, _arg_15: number, _arg_16:_Str_8176[]) + { + this._Str_6036 = k; + this._state = _arg_2; + this._Str_2629 = _arg_3; + this._Str_21044 = _arg_4; + this._issueAgeInMilliseconds = _arg_5; + this._priority = _arg_6; + this._Str_9559 = _arg_7; + this._Str_21130 = _arg_8; + this._Str_19722 = _arg_9; + this._Str_2797 = _arg_10; + this._Str_5502 = _arg_11; + this._Str_9859 = _arg_12; + this._Str_21393 = _arg_13; + this._message = _arg_14; + this._Str_10679 = _arg_15; + this._Str_15205 = _arg_16; + this._Str_19084 = 0; //getTimer(); + } + + public get _Str_2869(): number + { + return this._Str_6036; + } + + public get state(): number + { + return this._state; + } + + public get _Str_2712(): number + { + return this._Str_2629; + } + + public get _Str_7437(): number + { + return this._Str_21044; + } + + public get issueAgeInMilliseconds(): number + { + return this._issueAgeInMilliseconds; + } + + public get priority(): number + { + return this._priority; + } + + public get _Str_16842(): number + { + return this._Str_9559; + } + + public get _Str_19929(): number + { + return this._Str_21130; + } + + public get _Str_19615(): string + { + return this._Str_19722; + } + + public get _Str_2662(): number + { + return this._Str_2797; + } + + public get _Str_5842(): string + { + return this._Str_5502; + } + + public get _Str_5547(): number + { + return this._Str_9859; + } + + public get _Str_22164(): string + { + return this._Str_21393; + } + + public get message(): string + { + return this._message; + } + + public get _Str_20325(): number + { + return this._Str_10679; + } + + public get _Str_26050(): _Str_8176[] + { + return this._Str_15205; + } + + public dispose(): void + { + + if(this.disposed) + { + return; + } + for(const k of this._Str_15205) + { + k.dispose(); + } + this._Str_15205 = []; + this._disposed = true; + } + + public get disposed(): boolean + { + return this._disposed; + } + + public _Str_15885(k: number): string + { + const _local_2: number = (((this._issueAgeInMilliseconds + k) - this._Str_19084) / 1000); + const _local_3: number = (_local_2 / 60); + const _local_4: number = (_local_3 % 60); + const _local_5: number = (_local_3 / 60); + const _local_6: string = (((_local_4 < 10) ? '0' : '') + _local_4); + const _local_7: string = (((_local_5 < 10) ? '0' : '') + _local_5); + return (_local_7 + ':') + _local_6; + } +} diff --git a/src/nitro/communication/messages/parser/modtool/utils/_Str_5018.ts b/src/nitro/communication/messages/parser/modtool/utils/_Str_5018.ts new file mode 100644 index 00000000..9eaa1806 --- /dev/null +++ b/src/nitro/communication/messages/parser/modtool/utils/_Str_5018.ts @@ -0,0 +1,138 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { _Str_5460 } from './_Str_5460'; +import { _Str_2484 } from './_Str_2484'; + +export class _Str_5018 +{ + private _Str_12818:string[]; + private _Str_14428:string[]; + private _issues:_Str_2484[]; + private _Str_21327:boolean; + private _Str_20034:boolean; + private _Str_21542:boolean; + private _Str_22205:boolean; + private _Str_22169:boolean; + private _Str_19231:boolean; + private _Str_19156:boolean; + + private _disposed: boolean = false; + + constructor(wrapper: IMessageDataWrapper) + { + const local2 = new _Str_5460(); + this._issues = []; + this._Str_12818 = []; + this._Str_14428= []; + + let local3 = wrapper.readInt(); + let i = 0; + while(i < local3) + { + if(local2.parse(wrapper)) + { + this._issues.push(local2._Str_22192); + } + i++; + } + + local3 = wrapper.readInt(); + i = 0; + while(i < local3) + { + this._Str_12818.push(wrapper.readString()); + i++; + } + + local3 = wrapper.readInt(); + i = 0; + while(i < local3) + { + wrapper.readString(); + i++; + } + + this._Str_21327 = wrapper.readBoolean(); + this._Str_20034 = wrapper.readBoolean(); + this._Str_21542 = wrapper.readBoolean(); + this._Str_22205 = wrapper.readBoolean(); + this._Str_22169 = wrapper.readBoolean(); + this._Str_19231 = wrapper.readBoolean(); + this._Str_19156 = wrapper.readBoolean(); + local3 = wrapper.readInt(); + i = 0; + while(i < local3) + { + this._Str_14428.push(wrapper.readString()); + i++; + } + + + } + public dispose():void + { + if(this._disposed) + { + return; + } + this._disposed = true; + this._Str_12818 = null; + this._Str_14428 = null; + this._issues = null; + } + + public get disposed():boolean + { + return this._disposed; + } + + public get _Str_15690():string[] + { + return this._Str_12818; + } + + public get _Str_18336():string[] + { + return this._Str_14428; + } + + public get issues():_Str_2484[] + { + return this._issues; + } + + public get _Str_24070():boolean + { + return this._Str_21327; + } + + public get _Str_12765():boolean + { + return this._Str_20034; + } + + public get _Str_18465():boolean + { + return this._Str_21542; + } + + public get _Str_20397():boolean + { + return this._Str_22205; + } + + public get _Str_21242():boolean + { + return this._Str_22169; + } + + public get _Str_24851():boolean + { + return this._Str_19231; + } + + public get _Str_24333():boolean + { + return this._Str_19156; + } + +} diff --git a/src/nitro/communication/messages/parser/modtool/utils/_Str_5460.ts b/src/nitro/communication/messages/parser/modtool/utils/_Str_5460.ts new file mode 100644 index 00000000..7b706a61 --- /dev/null +++ b/src/nitro/communication/messages/parser/modtool/utils/_Str_5460.ts @@ -0,0 +1,50 @@ +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; +import { _Str_2484 } from './_Str_2484'; +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { _Str_8176 } from './_Str_8176'; + +export class _Str_5460 implements IMessageParser +{ + private _Str_13730:_Str_2484; + + + public get _Str_22192():_Str_2484 + { + return this._Str_13730; + } + + public flush():boolean + { + this._Str_13730 = null; + return true; + } + + public parse(k:IMessageDataWrapper):boolean + { + const _local_2:number = k.readInt(); + const _local_3:number = k.readInt(); + const _local_4:number = k.readInt(); + const _local_5:number = k.readInt(); + const _local_6:number = k.readInt(); + const _local_7:number = k.readInt(); + const _local_8:number = k.readInt(); + const _local_9:number = k.readInt(); + const _local_10:string = k.readString(); + const _local_11:number = k.readInt(); + const _local_12:string = k.readString(); + const _local_13:number = k.readInt(); + const _local_14:string = k.readString(); + const _local_15:string = k.readString(); + const _local_16:number = k.readInt(); + const _local_17:number = k.readInt(); + const _local_18:_Str_8176[] = []; + let _local_19 = 0; + while(_local_19 < _local_17) + { + _local_18.push(new _Str_8176(k)); + _local_19++; + } + this._Str_13730 = new _Str_2484(_local_2, _local_3, _local_4, _local_5, _local_6, _local_7, _local_8, _local_9, _local_10, _local_11, _local_12, _local_13, _local_14, _local_15, _local_16, _local_18); + return true; + } +} diff --git a/src/nitro/communication/messages/parser/modtool/utils/_Str_5467.ts b/src/nitro/communication/messages/parser/modtool/utils/_Str_5467.ts new file mode 100644 index 00000000..93ef6361 --- /dev/null +++ b/src/nitro/communication/messages/parser/modtool/utils/_Str_5467.ts @@ -0,0 +1,145 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; + +export class _Str_5467 +{ + private _userId:number; + private _userName:string; + private _Str_19258:number; + private _Str_20876:number; + private _online:boolean; + private _Str_21621:number; + private _Str_20013:number; + private _Str_20917:number; + private _Str_20349:number; + private _Str_21386:number; + private _Str_20848:string; + private _Str_21819:string; + private _Str_20982:number; + private _Str_19460:number; + private _Str_22254:string; + private _figure:string; + private _Str_20625:string; + private _Str_19116:string = ''; + private _Str_20729:number = 0; + + constructor(wrapper: IMessageDataWrapper) + { + this._userId = wrapper.readInt(); + this._userName = wrapper.readString(); + this._figure = wrapper.readString(); + this._Str_19258 = wrapper.readInt(); + this._Str_20876 = wrapper.readInt(); + this._online = wrapper.readBoolean(); + this._Str_21621 = wrapper.readInt(); + this._Str_20013 = wrapper.readInt(); + this._Str_20917 = wrapper.readInt(); + this._Str_20349 = wrapper.readInt(); + this._Str_21386 = wrapper.readInt(); + this._Str_20848 = wrapper.readString(); + this._Str_21819 = wrapper.readString(); + this._Str_20982 = wrapper.readInt(); + this._Str_19460 = wrapper.readInt(); + this._Str_22254 = wrapper.readString(); + this._Str_20625 = wrapper.readString(); + if(wrapper.bytesAvailable) + { + this._Str_19116 = wrapper.readString(); + this._Str_20729 = wrapper.readInt(); + } + } + + public get userId():number + { + return this._userId; + } + + public get userName():string + { + return this._userName; + } + + public get figure():string + { + return this._figure; + } + + public get _Str_24334():number + { + return this._Str_19258; + } + + public get _Str_23276():number + { + return this._Str_20876; + } + + public get online():boolean + { + return this._online; + } + + public get _Str_24656():number + { + return this._Str_21621; + } + + public get _Str_22987():number + { + return this._Str_20013; + } + + public get _Str_16987():number + { + return this._Str_20917; + } + + public get _Str_20373():number + { + return this._Str_20349; + } + + public get _Str_24526():number + { + return this._Str_21386; + } + + public get _Str_23969():string + { + return this._Str_20848; + } + + public get _Str_22786():string + { + return this._Str_21819; + } + + public get _Str_25657():number + { + return this._Str_20982; + } + + public get _Str_22700():number + { + return this._Str_19460; + } + + public get _Str_20219():string + { + return this._Str_22254; + } + + public get _Str_22262():string + { + return this._Str_20625; + } + + public get _Str_24447():string + { + return this._Str_19116; + } + + public get _Str_19137():number + { + return this._Str_20729; + } +} diff --git a/src/nitro/communication/messages/parser/modtool/utils/_Str_8176.ts b/src/nitro/communication/messages/parser/modtool/utils/_Str_8176.ts new file mode 100644 index 00000000..925970bc --- /dev/null +++ b/src/nitro/communication/messages/parser/modtool/utils/_Str_8176.ts @@ -0,0 +1,45 @@ +import { IDisposable } from '../../../../../../core/common/disposable/IDisposable'; +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; + +export class _Str_8176 implements IDisposable +{ + private _pattern:string; + private _startIndex:number; + private _endIndex:number; + private _disposed:boolean = false; + + constructor(k:IMessageDataWrapper) + { + this._pattern = k.readString(); + this._startIndex = k.readInt(); + this._endIndex = k.readInt(); + } + + public dispose():void + { + this._disposed = true; + this._pattern = ''; + this._startIndex = -1; + this._endIndex = -1; + } + + public get disposed():boolean + { + return this._disposed; + } + + public get pattern():string + { + return this._pattern; + } + + public get startIndex():number + { + return this._startIndex; + } + + public get endIndex():number + { + return this._endIndex; + } +} diff --git a/src/nitro/communication/messages/parser/navigator/NavigatorCategoriesParser.ts b/src/nitro/communication/messages/parser/navigator/NavigatorCategoriesParser.ts new file mode 100644 index 00000000..057d00ed --- /dev/null +++ b/src/nitro/communication/messages/parser/navigator/NavigatorCategoriesParser.ts @@ -0,0 +1,36 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; +import { NavigatorCategoryDataParser } from './NavigatorCategoryDataParser'; + +export class NavigatorCategoriesParser implements IMessageParser +{ + private _categories: NavigatorCategoryDataParser[]; + + public flush(): boolean + { + this._categories = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + let totalCategories = wrapper.readInt(); + + while(totalCategories > 0) + { + this._categories.push(new NavigatorCategoryDataParser(wrapper)); + + totalCategories--; + } + + return true; + } + + public get categories(): NavigatorCategoryDataParser[] + { + return this._categories; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/navigator/NavigatorCategoryDataParser.ts b/src/nitro/communication/messages/parser/navigator/NavigatorCategoryDataParser.ts new file mode 100644 index 00000000..2d56cdb3 --- /dev/null +++ b/src/nitro/communication/messages/parser/navigator/NavigatorCategoryDataParser.ts @@ -0,0 +1,83 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; + +export class NavigatorCategoryDataParser +{ + private _id: number; + private _name: string; + private _visible: boolean; + private _automatic: boolean; + private _automaticCategoryKey: string; + private _globalCategoryKey: string; + private _staffOnly: boolean; + + constructor(wrapper: IMessageDataWrapper) + { + if(!wrapper) throw new Error('invalid_wrapper'); + + this.flush(); + this.parse(wrapper); + } + + public flush(): boolean + { + this._id = -1; + this._name = null; + this._visible = false; + this._automatic = false; + this._automaticCategoryKey = null; + this._globalCategoryKey = null; + this._staffOnly = false; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._id = wrapper.readInt(); + this._name = wrapper.readString(); + this._visible = wrapper.readBoolean(); + this._automatic = wrapper.readBoolean(); + this._automaticCategoryKey = wrapper.readString(); + this._globalCategoryKey = wrapper.readString(); + this._staffOnly = wrapper.readBoolean(); + + return true; + } + + public get id(): number + { + return this._id; + } + + public get name(): string + { + return this._name; + } + + public get visible(): boolean + { + return this._visible; + } + + public get automatic(): boolean + { + return this._automatic; + } + + public get automaticCategoryKey(): string + { + return this._automaticCategoryKey; + } + + public get globalCategoryKey(): string + { + return this._globalCategoryKey; + } + + public get staffOnly(): boolean + { + return this._staffOnly; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/navigator/NavigatorCollapsedParser.ts b/src/nitro/communication/messages/parser/navigator/NavigatorCollapsedParser.ts new file mode 100644 index 00000000..04fcdb08 --- /dev/null +++ b/src/nitro/communication/messages/parser/navigator/NavigatorCollapsedParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; + +export class NavigatorCollapsedParser implements IMessageParser +{ + private _categories: string[]; + + public flush(): boolean + { + this._categories = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + let totalCategories = wrapper.readInt(); + + while(totalCategories > 0) + { + this._categories.push(wrapper.readString()); + + totalCategories--; + } + + return true; + } + + public get categories(): string[] + { + return this._categories; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/navigator/NavigatorEventCategoriesParser.ts b/src/nitro/communication/messages/parser/navigator/NavigatorEventCategoriesParser.ts new file mode 100644 index 00000000..e2c311b6 --- /dev/null +++ b/src/nitro/communication/messages/parser/navigator/NavigatorEventCategoriesParser.ts @@ -0,0 +1,36 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; +import { NavigatorEventCategoryDataParser } from './NavigatorEventCategoryDataParser'; + +export class NavigatorEventCategoriesParser implements IMessageParser +{ + private _categories: NavigatorEventCategoryDataParser[]; + + public flush(): boolean + { + this._categories = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + let totalCategories = wrapper.readInt(); + + while(totalCategories > 0) + { + this._categories.push(new NavigatorEventCategoryDataParser(wrapper)); + + totalCategories--; + } + + return true; + } + + public get categories(): NavigatorEventCategoryDataParser[] + { + return this._categories; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/navigator/NavigatorEventCategoryDataParser.ts b/src/nitro/communication/messages/parser/navigator/NavigatorEventCategoryDataParser.ts new file mode 100644 index 00000000..65f6bb66 --- /dev/null +++ b/src/nitro/communication/messages/parser/navigator/NavigatorEventCategoryDataParser.ts @@ -0,0 +1,51 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; + +export class NavigatorEventCategoryDataParser +{ + private _id: number; + private _name: string; + private _visible: boolean; + + constructor(wrapper: IMessageDataWrapper) + { + if(!wrapper) throw new Error('invalid_wrapper'); + + this.flush(); + this.parse(wrapper); + } + + public flush(): boolean + { + this._id = -1; + this._name = null; + this._visible = false; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._id = wrapper.readInt(); + this._name = wrapper.readString(); + this._visible = wrapper.readBoolean(); + + return true; + } + + public get id(): number + { + return this._id; + } + + public get name(): string + { + return this._name; + } + + public get visible(): boolean + { + return this._visible; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/navigator/NavigatorHomeRoomParser.ts b/src/nitro/communication/messages/parser/navigator/NavigatorHomeRoomParser.ts new file mode 100644 index 00000000..ba60fe72 --- /dev/null +++ b/src/nitro/communication/messages/parser/navigator/NavigatorHomeRoomParser.ts @@ -0,0 +1,36 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; + +export class NavigatorHomeRoomParser implements IMessageParser +{ + private _homeRoomId: number; + private _roomIdToEnter: number; + + public flush(): boolean + { + this._homeRoomId = -1; + this._roomIdToEnter = -1; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._homeRoomId = wrapper.readInt(); + this._roomIdToEnter = wrapper.readInt(); + + return true; + } + + public get homeRoomId(): number + { + return this._homeRoomId; + } + + public get roomIdToEnter(): number + { + return this._roomIdToEnter; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/navigator/NavigatorLiftedDataParser.ts b/src/nitro/communication/messages/parser/navigator/NavigatorLiftedDataParser.ts new file mode 100644 index 00000000..605b7f77 --- /dev/null +++ b/src/nitro/communication/messages/parser/navigator/NavigatorLiftedDataParser.ts @@ -0,0 +1,59 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; + +export class NavigatorLiftedDataParser +{ + private _roomId: number; + private _areaId: number; + private _image: string; + private _caption: string; + + constructor(wrapper: IMessageDataWrapper) + { + if(!wrapper) throw new Error('invalid_wrapper'); + + this.flush(); + this.parse(wrapper); + } + + public flush(): boolean + { + this._roomId = -1; + this._areaId = -1; + this._image = null; + this._caption = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._roomId = wrapper.readInt(); + this._areaId = wrapper.readInt(); + this._image = wrapper.readString(); + this._caption = wrapper.readString(); + + return true; + } + + public get roomId(): number + { + return this._roomId; + } + + public get areaId(): number + { + return this._areaId; + } + + public get image(): string + { + return this._image; + } + + public get caption(): string + { + return this._caption; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/navigator/NavigatorLiftedParser.ts b/src/nitro/communication/messages/parser/navigator/NavigatorLiftedParser.ts new file mode 100644 index 00000000..0aabb983 --- /dev/null +++ b/src/nitro/communication/messages/parser/navigator/NavigatorLiftedParser.ts @@ -0,0 +1,36 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; +import { NavigatorLiftedDataParser } from './NavigatorLiftedDataParser'; + +export class NavigatorLiftedParser implements IMessageParser +{ + private _rooms: NavigatorLiftedDataParser[]; + + public flush(): boolean + { + this._rooms = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + let totalRooms = wrapper.readInt(); + + while(totalRooms > 0) + { + this._rooms.push(new NavigatorLiftedDataParser(wrapper)); + + totalRooms--; + } + + return true; + } + + public get rooms(): NavigatorLiftedDataParser[] + { + return this._rooms; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/navigator/NavigatorMetadataParser.ts b/src/nitro/communication/messages/parser/navigator/NavigatorMetadataParser.ts new file mode 100644 index 00000000..3f747206 --- /dev/null +++ b/src/nitro/communication/messages/parser/navigator/NavigatorMetadataParser.ts @@ -0,0 +1,36 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; +import { NavigatorTopLevelContext } from './utils/NavigatorTopLevelContext'; + +export class NavigatorMetadataParser implements IMessageParser +{ + private _topLevelContexts: NavigatorTopLevelContext[]; + + public flush(): boolean + { + this._topLevelContexts = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + let totalContexts = wrapper.readInt(); + + while(totalContexts > 0) + { + this._topLevelContexts.push(new NavigatorTopLevelContext(wrapper)); + + totalContexts--; + } + + return true; + } + + public get topLevelContexts(): NavigatorTopLevelContext[] + { + return this._topLevelContexts; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/navigator/NavigatorOpenRoomCreatorParser.ts b/src/nitro/communication/messages/parser/navigator/NavigatorOpenRoomCreatorParser.ts new file mode 100644 index 00000000..9923eb6e --- /dev/null +++ b/src/nitro/communication/messages/parser/navigator/NavigatorOpenRoomCreatorParser.ts @@ -0,0 +1,17 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; + +export class NavigatorOpenRoomCreatorParser implements IMessageParser +{ + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + return true; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/navigator/NavigatorSearchParser.ts b/src/nitro/communication/messages/parser/navigator/NavigatorSearchParser.ts new file mode 100644 index 00000000..e2a6f403 --- /dev/null +++ b/src/nitro/communication/messages/parser/navigator/NavigatorSearchParser.ts @@ -0,0 +1,29 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; +import { NavigatorSearchResultSet } from './utils/NavigatorSearchResultSet'; + +export class NavigatorSearchParser implements IMessageParser +{ + private _result: NavigatorSearchResultSet; + + public flush(): boolean + { + this._result = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._result = new NavigatorSearchResultSet(wrapper); + + return true; + } + + public get result(): NavigatorSearchResultSet + { + return this._result; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/navigator/NavigatorSearchesParser.ts b/src/nitro/communication/messages/parser/navigator/NavigatorSearchesParser.ts new file mode 100644 index 00000000..753720bb --- /dev/null +++ b/src/nitro/communication/messages/parser/navigator/NavigatorSearchesParser.ts @@ -0,0 +1,36 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; +import { NavigatorSavedSearch } from './utils/NavigatorSavedSearch'; + +export class NavigatorSearchesParser implements IMessageParser +{ + private _searches: NavigatorSavedSearch[]; + + public flush(): boolean + { + this._searches = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + let totalSearches = wrapper.readInt(); + + while(totalSearches > 0) + { + this._searches.push(new NavigatorSavedSearch(wrapper)); + + totalSearches--; + } + + return true; + } + + public get searches(): NavigatorSavedSearch[] + { + return this._searches; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/navigator/NavigatorSettingsParser.ts b/src/nitro/communication/messages/parser/navigator/NavigatorSettingsParser.ts new file mode 100644 index 00000000..c0f7b7e8 --- /dev/null +++ b/src/nitro/communication/messages/parser/navigator/NavigatorSettingsParser.ts @@ -0,0 +1,68 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; + +export class NavigatorSettingsParser implements IMessageParser +{ + private _windowX: number; + private _windowY: number; + private _windowWidth: number; + private _windowHeight: number; + private _leftPanelHidden: boolean; + private _resultsMode: number; + + public flush(): boolean + { + this._windowX = 0; + this._windowY = 0; + this._windowWidth = 0; + this._windowHeight = 0; + this._leftPanelHidden = false; + this._resultsMode = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._windowX = wrapper.readInt(); + this._windowY = wrapper.readInt(); + this._windowWidth = wrapper.readInt(); + this._windowHeight = wrapper.readInt(); + this._leftPanelHidden = wrapper.readBoolean(); + this._resultsMode = wrapper.readInt(); + + return true; + } + + public get windowX(): number + { + return this._windowX; + } + + public get windowY(): number + { + return this._windowY; + } + + public get windowWidth(): number + { + return this._windowWidth; + } + + public get windowHeight(): number + { + return this._windowHeight; + } + + public get leftPanelHidden(): boolean + { + return this._leftPanelHidden; + } + + public get resultsMode(): number + { + return this._resultsMode; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/navigator/utils/NavigatorSavedSearch.ts b/src/nitro/communication/messages/parser/navigator/utils/NavigatorSavedSearch.ts new file mode 100644 index 00000000..38467db3 --- /dev/null +++ b/src/nitro/communication/messages/parser/navigator/utils/NavigatorSavedSearch.ts @@ -0,0 +1,59 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; + +export class NavigatorSavedSearch +{ + private _id: number; + private _code: string; + private _filter: string; + private _localization: string; + + constructor(wrapper: IMessageDataWrapper) + { + if(!wrapper) throw new Error('invalid_wrapper'); + + this.flush(); + this.parse(wrapper); + } + + public flush(): boolean + { + this._id = -1; + this._code = null; + this._filter = null; + this._localization = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._id = wrapper.readInt(); + this._code = wrapper.readString(); + this._filter = wrapper.readString(); + this._localization = wrapper.readString(); + + return true; + } + + public get id(): number + { + return this._id; + } + + public get code(): string + { + return this._code; + } + + public get filter(): string + { + return this._filter; + } + + public get localization(): string + { + return this._localization; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/navigator/utils/NavigatorSearchResultList.ts b/src/nitro/communication/messages/parser/navigator/utils/NavigatorSearchResultList.ts new file mode 100644 index 00000000..358d2ae2 --- /dev/null +++ b/src/nitro/communication/messages/parser/navigator/utils/NavigatorSearchResultList.ts @@ -0,0 +1,84 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { RoomDataParser } from '../../room/data/RoomDataParser'; + +export class NavigatorSearchResultList +{ + private _code: string; + private _data: string; + private _action: number; + private _closed: boolean; + private _mode: number; + private _rooms: RoomDataParser[]; + + constructor(wrapper: IMessageDataWrapper) + { + if(!wrapper) throw new Error('invalid_wrapper'); + + this.flush(); + this.parse(wrapper); + } + + public flush(): boolean + { + this._code = null; + this._data = null; + this._action = -1; + this._closed = false; + this._mode = -1; + this._rooms = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._code = wrapper.readString(); + this._data = wrapper.readString(); + this._action = wrapper.readInt(); + this._closed = wrapper.readBoolean(); + this._mode = wrapper.readInt(); + + let totalRooms = wrapper.readInt(); + + while(totalRooms > 0) + { + this._rooms.push(new RoomDataParser(wrapper)); + + totalRooms--; + } + + return true; + } + + public get code(): string + { + return this._code; + } + + public get data(): string + { + return this._data; + } + + public get action(): number + { + return this._action; + } + + public get closed(): boolean + { + return this._closed; + } + + public get mode(): number + { + return this._mode; + } + + public get rooms(): RoomDataParser[] + { + return this._rooms; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/navigator/utils/NavigatorSearchResultSet.ts b/src/nitro/communication/messages/parser/navigator/utils/NavigatorSearchResultSet.ts new file mode 100644 index 00000000..470bb80f --- /dev/null +++ b/src/nitro/communication/messages/parser/navigator/utils/NavigatorSearchResultSet.ts @@ -0,0 +1,60 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { NavigatorSearchResultList } from './NavigatorSearchResultList'; + +export class NavigatorSearchResultSet +{ + private _code: string; + private _data: string; + private _results: NavigatorSearchResultList[]; + + constructor(wrapper: IMessageDataWrapper) + { + if(!wrapper) throw new Error('invalid_wrapper'); + + this.flush(); + this.parse(wrapper); + } + + public flush(): boolean + { + this._code = null; + this._data = null; + this._results = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._code = wrapper.readString(); + this._data = wrapper.readString(); + + let totalResults = wrapper.readInt(); + + while(totalResults > 0) + { + this._results.push(new NavigatorSearchResultList(wrapper)); + + totalResults--; + } + + return true; + } + + public get code(): string + { + return this._code; + } + + public get data(): string + { + return this._data; + } + + public get results(): NavigatorSearchResultList[] + { + return this._results; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/navigator/utils/NavigatorTopLevelContext.ts b/src/nitro/communication/messages/parser/navigator/utils/NavigatorTopLevelContext.ts new file mode 100644 index 00000000..b2b8980d --- /dev/null +++ b/src/nitro/communication/messages/parser/navigator/utils/NavigatorTopLevelContext.ts @@ -0,0 +1,52 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { NavigatorSavedSearch } from './NavigatorSavedSearch'; + +export class NavigatorTopLevelContext +{ + private _code: string; + private _savedSearches: NavigatorSavedSearch[]; + + constructor(wrapper: IMessageDataWrapper) + { + if(!wrapper) throw new Error('invalid_wrapper'); + + this.flush(); + this.parse(wrapper); + } + + public flush(): boolean + { + this._code = null; + this._savedSearches = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._code = wrapper.readString(); + + let totalSavedSearches = wrapper.readInt(); + + while(totalSavedSearches > 0) + { + this._savedSearches.push(new NavigatorSavedSearch(wrapper)); + + totalSavedSearches--; + } + + return true; + } + + public get code(): string + { + return this._code; + } + + public get savedSearches(): NavigatorSavedSearch[] + { + return this._savedSearches; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/notifications/BotErrorEventParser.ts b/src/nitro/communication/messages/parser/notifications/BotErrorEventParser.ts new file mode 100644 index 00000000..b7c30b85 --- /dev/null +++ b/src/nitro/communication/messages/parser/notifications/BotErrorEventParser.ts @@ -0,0 +1,27 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; + +export class BotErrorEventParser implements IMessageParser +{ + private _errorCode: number; + + public flush(): boolean + { + this._errorCode = -1; + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._errorCode = wrapper.readInt(); + + return true; + } + + public get errorCode(): number + { + return this._errorCode; + } +} diff --git a/src/nitro/communication/messages/parser/notifications/HabboBroadcastMessageParser.ts b/src/nitro/communication/messages/parser/notifications/HabboBroadcastMessageParser.ts new file mode 100644 index 00000000..7bb96b7b --- /dev/null +++ b/src/nitro/communication/messages/parser/notifications/HabboBroadcastMessageParser.ts @@ -0,0 +1,28 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; + +export class HabboBroadcastMessageParser implements IMessageParser +{ + private _message: string; + + public flush(): boolean + { + this._message = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._message = wrapper.readString(); + + return true; + } + + public get message(): string + { + return this._message; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/notifications/HotelWillShutdownParser.ts b/src/nitro/communication/messages/parser/notifications/HotelWillShutdownParser.ts new file mode 100644 index 00000000..bd7f8fc8 --- /dev/null +++ b/src/nitro/communication/messages/parser/notifications/HotelWillShutdownParser.ts @@ -0,0 +1,28 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; + +export class HotelWillShutdownParser implements IMessageParser +{ + private _minutes: number; + + public flush(): boolean + { + this._minutes = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._minutes = wrapper.readInt(); + + return true; + } + + public get minutes(): number + { + return this._minutes; + } +} diff --git a/src/nitro/communication/messages/parser/notifications/MOTDNotificationParser.ts b/src/nitro/communication/messages/parser/notifications/MOTDNotificationParser.ts new file mode 100644 index 00000000..a3e6695c --- /dev/null +++ b/src/nitro/communication/messages/parser/notifications/MOTDNotificationParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; + +export class MOTDNotificationParser implements IMessageParser +{ + private _messages: string[] + + public flush(): boolean + { + this._messages = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + let totalMessages = wrapper.readInt(); + + while(totalMessages > 0) + { + this._messages.push(wrapper.readString()); + + totalMessages--; + } + + return true; + } + + public get messages(): string[] + { + return this._messages; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/notifications/NotificationDialogMessageParser.ts b/src/nitro/communication/messages/parser/notifications/NotificationDialogMessageParser.ts new file mode 100644 index 00000000..7c16a5e1 --- /dev/null +++ b/src/nitro/communication/messages/parser/notifications/NotificationDialogMessageParser.ts @@ -0,0 +1,44 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; + +export class NotificationDialogMessageParser implements IMessageParser +{ + private _type: string; + private _parameters: Map; + + public flush(): boolean + { + this._type = null; + this._parameters = new Map(); + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._type = wrapper.readString(); + + let totalParameters = wrapper.readInt(); + + while(totalParameters > 0) + { + this._parameters.set(wrapper.readString(), wrapper.readString()); + + totalParameters--; + } + + return true; + } + + public get type(): string + { + return this._type; + } + + public get parameters(): Map + { + return this._parameters; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/notifications/PetPlacingErrorEventParser.ts b/src/nitro/communication/messages/parser/notifications/PetPlacingErrorEventParser.ts new file mode 100644 index 00000000..9fbe2d6b --- /dev/null +++ b/src/nitro/communication/messages/parser/notifications/PetPlacingErrorEventParser.ts @@ -0,0 +1,27 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; + +export class PetPlacingErrorEventParser implements IMessageParser +{ + private _errorCode: number; + + public flush(): boolean + { + this._errorCode = -1; + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._errorCode = wrapper.readInt(); + + return true; + } + + public get errorCode(): number + { + return this._errorCode; + } +} diff --git a/src/nitro/communication/messages/parser/notifications/RespectReceivedParser.ts b/src/nitro/communication/messages/parser/notifications/RespectReceivedParser.ts new file mode 100644 index 00000000..be97aedb --- /dev/null +++ b/src/nitro/communication/messages/parser/notifications/RespectReceivedParser.ts @@ -0,0 +1,36 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; + +export class RespectReceivedParser implements IMessageParser +{ + private _userId: number; + private _respectsReceived: number; + + public flush(): boolean + { + this._userId = 0; + this._respectsReceived = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._userId = wrapper.readInt(); + this._respectsReceived = wrapper.readInt(); + + return true; + } + + public get userId(): number + { + return this._userId; + } + + public get respectsReceived(): number + { + return this._respectsReceived; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/notifications/UnseenItemsParser.ts b/src/nitro/communication/messages/parser/notifications/UnseenItemsParser.ts new file mode 100644 index 00000000..c91e3c51 --- /dev/null +++ b/src/nitro/communication/messages/parser/notifications/UnseenItemsParser.ts @@ -0,0 +1,53 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; +import { AdvancedMap } from '../../../../../core/utils/AdvancedMap'; + +export class UnseenItemsParser implements IMessageParser +{ + private _items: AdvancedMap; + + public flush(): boolean + { + this._items = new AdvancedMap(); + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + let totalUnseen = wrapper.readInt(); + + while(totalUnseen > 0) + { + const category = wrapper.readInt(); + + let totalItems = wrapper.readInt(); + const itemIds: number[] = []; + + while(totalItems > 0) + { + itemIds.push(wrapper.readInt()); + + totalItems--; + } + + this._items.add(category, itemIds); + + totalUnseen--; + } + + return true; + } + + public getItemsByCategory(category: number): number[] + { + return this._items.getValue(category); + } + + public get categories(): number[] + { + return this._items.getKeys(); + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/room/access/RoomEnterErrorParser.ts b/src/nitro/communication/messages/parser/room/access/RoomEnterErrorParser.ts new file mode 100644 index 00000000..1bae004e --- /dev/null +++ b/src/nitro/communication/messages/parser/room/access/RoomEnterErrorParser.ts @@ -0,0 +1,41 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class RoomEnterErrorParser implements IMessageParser +{ + public static FULL_ERROR: number = 1; + public static _Str_19431: number = 2; + public static QUEUE_ERROR: number = 3; + public static BANNED: number = 4; + + private _reason: number; + private _parameter: string; + + public flush(): boolean + { + this._reason = 0; + this._parameter = ''; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._reason = wrapper.readInt(); + this._parameter = wrapper.readString(); + + return true; + } + + public get reason(): number + { + return this._reason; + } + + public get parameter(): string + { + return this._parameter; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/room/access/RoomEnterParser.ts b/src/nitro/communication/messages/parser/room/access/RoomEnterParser.ts new file mode 100644 index 00000000..7a8c769d --- /dev/null +++ b/src/nitro/communication/messages/parser/room/access/RoomEnterParser.ts @@ -0,0 +1,17 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class RoomEnterParser implements IMessageParser +{ + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + return true; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/room/access/RoomFowardParser.ts b/src/nitro/communication/messages/parser/room/access/RoomFowardParser.ts new file mode 100644 index 00000000..ca7664d7 --- /dev/null +++ b/src/nitro/communication/messages/parser/room/access/RoomFowardParser.ts @@ -0,0 +1,28 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class RoomFowardParser implements IMessageParser +{ + private _roomId: number; + + public flush(): boolean + { + this._roomId = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._roomId = wrapper.readInt(); + + return true; + } + + public get roomId(): number + { + return this._roomId; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/room/access/doorbell/RoomDoorbellAcceptedParser.ts b/src/nitro/communication/messages/parser/room/access/doorbell/RoomDoorbellAcceptedParser.ts new file mode 100644 index 00000000..dddafe8f --- /dev/null +++ b/src/nitro/communication/messages/parser/room/access/doorbell/RoomDoorbellAcceptedParser.ts @@ -0,0 +1,28 @@ +import { IMessageDataWrapper } from '../../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../../core/communication/messages/IMessageParser'; + +export class RoomDoorbellAcceptedParser implements IMessageParser +{ + private _userName: string; + + public flush(): boolean + { + this._userName = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._userName = wrapper.readString(); + + return true; + } + + public get userName(): string + { + return this._userName; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/room/access/doorbell/RoomDoorbellParser.ts b/src/nitro/communication/messages/parser/room/access/doorbell/RoomDoorbellParser.ts new file mode 100644 index 00000000..c7bb1bbe --- /dev/null +++ b/src/nitro/communication/messages/parser/room/access/doorbell/RoomDoorbellParser.ts @@ -0,0 +1,28 @@ +import { IMessageDataWrapper } from '../../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../../core/communication/messages/IMessageParser'; + +export class RoomDoorbellParser implements IMessageParser +{ + private _userName: string; + + public flush(): boolean + { + this._userName = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._userName = wrapper.readString(); + + return true; + } + + public get userName(): string + { + return this._userName; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/room/access/doorbell/RoomDoorbellRejectedParser.ts b/src/nitro/communication/messages/parser/room/access/doorbell/RoomDoorbellRejectedParser.ts new file mode 100644 index 00000000..b5935c81 --- /dev/null +++ b/src/nitro/communication/messages/parser/room/access/doorbell/RoomDoorbellRejectedParser.ts @@ -0,0 +1,28 @@ +import { IMessageDataWrapper } from '../../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../../core/communication/messages/IMessageParser'; + +export class RoomDoorbellRejectedParser implements IMessageParser +{ + private _userName: string; + + public flush(): boolean + { + this._userName = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._userName = wrapper.readString(); + + return true; + } + + public get userName(): string + { + return this._userName; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/room/access/rights/RoomRightsClearParser.ts b/src/nitro/communication/messages/parser/room/access/rights/RoomRightsClearParser.ts new file mode 100644 index 00000000..530c97e8 --- /dev/null +++ b/src/nitro/communication/messages/parser/room/access/rights/RoomRightsClearParser.ts @@ -0,0 +1,17 @@ +import { IMessageDataWrapper } from '../../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../../core/communication/messages/IMessageParser'; + +export class RoomRightsClearParser implements IMessageParser +{ + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + return true; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/room/access/rights/RoomRightsOwnerParser.ts b/src/nitro/communication/messages/parser/room/access/rights/RoomRightsOwnerParser.ts new file mode 100644 index 00000000..06fa654e --- /dev/null +++ b/src/nitro/communication/messages/parser/room/access/rights/RoomRightsOwnerParser.ts @@ -0,0 +1,17 @@ +import { IMessageDataWrapper } from '../../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../../core/communication/messages/IMessageParser'; + +export class RoomRightsOwnerParser implements IMessageParser +{ + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + return true; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/room/access/rights/RoomRightsParser.ts b/src/nitro/communication/messages/parser/room/access/rights/RoomRightsParser.ts new file mode 100644 index 00000000..6f5f9100 --- /dev/null +++ b/src/nitro/communication/messages/parser/room/access/rights/RoomRightsParser.ts @@ -0,0 +1,29 @@ +import { IMessageDataWrapper } from '../../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../../core/communication/messages/IMessageParser'; +import { RoomControllerLevel } from '../../../../../../session/enum/RoomControllerLevel'; + +export class RoomRightsParser implements IMessageParser +{ + private _controllerLevel: number; + + public flush(): boolean + { + this._controllerLevel = RoomControllerLevel.NONE; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._controllerLevel = wrapper.readInt(); + + return true; + } + + public get controllerLevel(): number + { + return this._controllerLevel; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/room/bots/BotCommandConfigurationParser.ts b/src/nitro/communication/messages/parser/room/bots/BotCommandConfigurationParser.ts new file mode 100644 index 00000000..142b5c9b --- /dev/null +++ b/src/nitro/communication/messages/parser/room/bots/BotCommandConfigurationParser.ts @@ -0,0 +1,43 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class BotCommandConfigurationParser implements IMessageParser +{ + private _botId: number; + private _commandId: number; + private _data: string; + + public flush(): boolean + { + this._botId = -1; + this._commandId = -1; + this._data = ''; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._botId = wrapper.readInt(); + this._commandId = wrapper.readInt(); + this._data = wrapper.readString(); + + return true; + } + + public get botId(): number + { + return this._botId; + } + public get commandId(): number + { + return this._commandId; + } + + public get data(): string + { + return this._data; + } +} diff --git a/src/nitro/communication/messages/parser/room/data/RoomChatParser.ts b/src/nitro/communication/messages/parser/room/data/RoomChatParser.ts new file mode 100644 index 00000000..8bbfb177 --- /dev/null +++ b/src/nitro/communication/messages/parser/room/data/RoomChatParser.ts @@ -0,0 +1,78 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; + +export class RoomChatParser +{ + public static _Str_19408: number = 0; + public static _Str_12787: number = 1; + public static _Str_16907: number = 0; + public static _Str_12581: number = 1; + public static _Str_16484: number = 2; + public static _Str_18404: number = 0; + public static _Str_17874: number = 1; + public static _Str_16469: number = 2; + public static _Str_21099: number = 0; + public static _Str_20763: number = 1; + public static _Str_22060: number = 2; + + private _mode: number; + private _weight: number; + private _speed: number; + private _distance: number; + private _protection: number; + + constructor(wrapper: IMessageDataWrapper) + { + if(!wrapper) throw new Error('invalid_wrapper'); + + this.flush(); + this.parse(wrapper); + } + + public flush(): boolean + { + this._mode = 0; + this._weight = 0; + this._speed = 0; + this._distance = 0; + this._protection = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._mode = wrapper.readInt(); + this._weight = wrapper.readInt(); + this._speed = wrapper.readInt(); + this._distance = wrapper.readInt(); + this._protection = wrapper.readInt(); + + return true; + } + + public get mode(): number + { + return this._mode; + } + public get weight(): number + { + return this._weight; + } + + public get speed(): number + { + return this._speed; + } + + public get distance(): number + { + return this._distance; + } + + public get protection(): number + { + return this._protection; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/room/data/RoomChatSettingsParser.ts b/src/nitro/communication/messages/parser/room/data/RoomChatSettingsParser.ts new file mode 100644 index 00000000..14da2e95 --- /dev/null +++ b/src/nitro/communication/messages/parser/room/data/RoomChatSettingsParser.ts @@ -0,0 +1,29 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; +import { RoomChatParser } from './RoomChatParser'; + +export class RoomChatSettingsParser implements IMessageParser +{ + private _chat: RoomChatParser; + + public flush(): boolean + { + this._chat = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._chat = new RoomChatParser(wrapper); + + return true; + } + + public get chat(): RoomChatParser + { + return this._chat; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/room/data/RoomDataParser.ts b/src/nitro/communication/messages/parser/room/data/RoomDataParser.ts new file mode 100644 index 00000000..262a6327 --- /dev/null +++ b/src/nitro/communication/messages/parser/room/data/RoomDataParser.ts @@ -0,0 +1,311 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; + +export class RoomDataParser +{ + public static THUMBNAIL_BITMASK = 1; + public static GROUPDATA_BITMASK = 2; + public static ROOMAD_BITMASK = 4; + public static SHOWOWNER_BITMASK = 8; + public static ALLOW_PETS_BITMASK = 16; + public static DISPLAY_ROOMAD_BITMASK = 32; + + public static OPEN_STATE = 0; + public static DOORBELL_STATE = 1; + public static PASSWORD_STATE = 2; + public static INVISIBLE_STATE = 4; + + private _roomId: number; + private _roomName: string; + private _showOwner: boolean; + private _ownerId: number; + private _ownerName: string; + private _doorMode: number; + private _userCount: number; + private _maxUserCount: number; + private _description: string; + private _tradeMode: number; + private _score: number; + private _ranking: number; + private _categoryId: number; + private _totalStars: number; + private _groupId: number; + private _groupName: string; + private _groupBadge: string; + private _tags: string[]; + private _bitMask: number; + private _thumbnail: any; + private _allowPets: boolean; + private _displayAd: boolean; + private _adName: string; + private _adDescription: string; + private _adExpiresIn: number; + private _allInRoomMuted: boolean; + private _canMute: boolean; + private _roomPicker: boolean; + private _officialRoomPicRef: string; + + constructor(wrapper: IMessageDataWrapper) + { + if(!wrapper) throw new Error('invalid_wrapper'); + + this.flush(); + this.parse(wrapper); + } + + public flush(): boolean + { + this._roomId = 0; + this._roomName = null; + this._ownerId = 0; + this._ownerName = null; + this._doorMode = 0; + this._userCount = 0; + this._maxUserCount = 0; + this._description = null; + this._tradeMode = 2; + this._score = 0; + this._ranking = 0; + this._categoryId = 0; + this._totalStars = 0; + this._groupId = 0; + this._groupName = null; + this._groupBadge = null; + this._tags = []; + this._bitMask = 0; + this._thumbnail = null; + this._allowPets = false; + this._showOwner = true; + this._displayAd = false; + this._adName = null; + this._adDescription = null; + this._adExpiresIn = 0; + this._allInRoomMuted = false; + this._canMute = false; + this._roomPicker = false; + this._officialRoomPicRef = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._roomId = wrapper.readInt(); + this._roomName = wrapper.readString(); + this._ownerId = wrapper.readInt(); + this._ownerName = wrapper.readString(); + this._doorMode = wrapper.readInt(); + this._userCount = wrapper.readInt(); + this._maxUserCount = wrapper.readInt(); + this._description = wrapper.readString(); + this._tradeMode = wrapper.readInt(); + this._score = wrapper.readInt(); + this._ranking = wrapper.readInt(); + this._categoryId = wrapper.readInt(); + + this.parseTags(wrapper); + + this.parseBitMask(wrapper); + + return true; + } + + private parseTags(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._tags = []; + + let totalTags = wrapper.readInt(); + + while(totalTags > 0) + { + this._tags.push(wrapper.readString()); + + totalTags--; + } + + return true; + } + + private parseBitMask(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._bitMask = wrapper.readInt(); + + if(this._bitMask & RoomDataParser.THUMBNAIL_BITMASK) this._officialRoomPicRef = wrapper.readString(); + + if(this._bitMask & RoomDataParser.GROUPDATA_BITMASK) + { + this._groupId = wrapper.readInt(); + this._groupName = wrapper.readString(); + this._groupBadge = wrapper.readString(); + } + + if(this._bitMask & RoomDataParser.ROOMAD_BITMASK) + { + this._adName = wrapper.readString(); + this._adDescription = wrapper.readString(); + this._adExpiresIn = wrapper.readInt(); + } + + this._showOwner = (this._bitMask & RoomDataParser.SHOWOWNER_BITMASK) > 0; + this._allowPets = (this._bitMask & RoomDataParser.ALLOW_PETS_BITMASK) > 0; + this._displayAd = (this._bitMask & RoomDataParser.DISPLAY_ROOMAD_BITMASK) > 0; + this._thumbnail = null; + + return true; + } + + public get roomId(): number + { + return this._roomId; + } + + public get roomName(): string + { + return this._roomName; + } + + public set roomName(name: string) + { + this._roomName = name; + } + + public get ownerId(): number + { + return this._ownerId; + } + + public get ownerName(): string + { + return this._ownerName; + } + + public get doorMode(): number + { + return this._doorMode; + } + + public get userCount(): number + { + return this._userCount; + } + + public get maxUserCount(): number + { + return this._maxUserCount; + } + + public get description(): string + { + return this._description; + } + + public get tradeMode(): number + { + return this._tradeMode; + } + + public get score(): number + { + return this._score; + } + + public get ranking(): number + { + return this._ranking; + } + + public get categoryId(): number + { + return this._categoryId; + } + + public get tags(): string[] + { + return this._tags; + } + + public get officialRoomPicRef(): string + { + return this._officialRoomPicRef; + } + + public get habboGroupId(): number + { + return this._groupId; + } + + public get groupName(): string + { + return this._groupName; + } + + public get groupBadgeCode(): string + { + return this._groupBadge; + } + + public get roomAdName(): string + { + return this._adName; + } + + public get roomAdDescription(): string + { + return this._adDescription; + } + + public get roomAdExpiresInMin(): number + { + return this._adExpiresIn; + } + + public get showOwner(): boolean + { + return this._showOwner; + } + + public get allowPets(): boolean + { + return this._allowPets; + } + + public get displayRoomEntryAd(): boolean + { + return this._displayAd; + } + + public get roomPicker(): boolean + { + return this._roomPicker; + } + + public set roomPicker(k: boolean) + { + this._roomPicker = k; + } + + public get canMute(): boolean + { + return this._canMute; + } + + public set canMute(k: boolean) + { + this._canMute = k; + } + + public get allInRoomMuted(): boolean + { + return this._allInRoomMuted; + } + + public set allInRoomMuted(k: boolean) + { + this._allInRoomMuted = k; + } +} diff --git a/src/nitro/communication/messages/parser/room/data/RoomInfoOwnerParser.ts b/src/nitro/communication/messages/parser/room/data/RoomInfoOwnerParser.ts new file mode 100644 index 00000000..a6b8ff72 --- /dev/null +++ b/src/nitro/communication/messages/parser/room/data/RoomInfoOwnerParser.ts @@ -0,0 +1,36 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class RoomInfoOwnerParser implements IMessageParser +{ + private _roomId: number; + private _isOwner: boolean; + + public flush(): boolean + { + this._roomId = 0; + this._isOwner = false; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._roomId = wrapper.readInt(); + this._isOwner = wrapper.readBoolean(); + + return true; + } + + public get roomId(): number + { + return this._roomId; + } + + public get isOwner(): boolean + { + return this._isOwner; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/room/data/RoomInfoParser.ts b/src/nitro/communication/messages/parser/room/data/RoomInfoParser.ts new file mode 100644 index 00000000..73a8dc1f --- /dev/null +++ b/src/nitro/communication/messages/parser/room/data/RoomInfoParser.ts @@ -0,0 +1,76 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; +import { RoomChatParser } from './RoomChatParser'; +import { RoomDataParser } from './RoomDataParser'; +import { RoomModerationParser } from './RoomModerationParser'; + +export class RoomInfoParser implements IMessageParser +{ + private _roomEnter: boolean; + private _roomForward: boolean; + private _staffPick: boolean; + private _data: RoomDataParser; + private _isGroupMember: boolean; + private _moderation: RoomModerationParser; + private _chat: RoomChatParser; + + public flush(): boolean + { + this._roomEnter = false; + this._roomForward = false; + this._staffPick = false; + this._data = null; + this._isGroupMember = false; + this._moderation = null; + this._chat = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._roomEnter = wrapper.readBoolean(); + this._data = new RoomDataParser(wrapper); + this._roomForward = wrapper.readBoolean(); + this.data.roomPicker = wrapper.readBoolean(); + this._isGroupMember = wrapper.readBoolean(); + this.data.allInRoomMuted = wrapper.readBoolean(); + this._moderation = new RoomModerationParser(wrapper); + this.data.canMute = wrapper.readBoolean(); + this._chat = new RoomChatParser(wrapper); + + return true; + } + + public get roomEnter(): boolean + { + return this._roomEnter; + } + + public get roomForward(): boolean + { + return this._roomForward; + } + + public get data(): RoomDataParser + { + return this._data; + } + + public get isGroupMember(): boolean + { + return this._isGroupMember; + } + + public get moderation(): RoomModerationParser + { + return this._moderation; + } + + public get chat(): RoomChatParser + { + return this._chat; + } +} diff --git a/src/nitro/communication/messages/parser/room/data/RoomModerationParser.ts b/src/nitro/communication/messages/parser/room/data/RoomModerationParser.ts new file mode 100644 index 00000000..4e321b86 --- /dev/null +++ b/src/nitro/communication/messages/parser/room/data/RoomModerationParser.ts @@ -0,0 +1,47 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; + +export class RoomModerationParser +{ + public static _Str_10707: number = 0; + public static _Str_5047: number = 1; + public static _Str_11537: number = 2; + + private _allowMute: number; + private _allowKick: number; + private _allowBan: number; + + constructor(wrapper: IMessageDataWrapper) + { + this.reset(); + this.parse(wrapper); + } + + private reset(): void + { + this._allowMute = 0; + this._allowKick = 0; + this._allowBan = 0; + } + + public parse(wrapper: IMessageDataWrapper): void + { + this._allowMute = wrapper.readInt(); + this._allowKick = wrapper.readInt(); + this._allowBan = wrapper.readInt(); + } + + public get allowMute(): number + { + return this._allowMute; + } + + public get allowKick(): number + { + return this._allowKick; + } + + public get allowBan(): number + { + return this._allowBan; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/room/data/RoomScoreParser.ts b/src/nitro/communication/messages/parser/room/data/RoomScoreParser.ts new file mode 100644 index 00000000..3060aa78 --- /dev/null +++ b/src/nitro/communication/messages/parser/room/data/RoomScoreParser.ts @@ -0,0 +1,36 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class RoomScoreParser implements IMessageParser +{ + private _totalLikes: number; + private _canLike: boolean; + + public flush(): boolean + { + this._totalLikes = 0; + this._canLike = false; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._totalLikes = wrapper.readInt(); + this._canLike = wrapper.readBoolean(); + + return true; + } + + public get totalLikes(): number + { + return this._totalLikes; + } + + public get canLike(): boolean + { + return this._canLike; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/room/data/RoomSettingsErrorParser.ts b/src/nitro/communication/messages/parser/room/data/RoomSettingsErrorParser.ts new file mode 100644 index 00000000..40f625fc --- /dev/null +++ b/src/nitro/communication/messages/parser/room/data/RoomSettingsErrorParser.ts @@ -0,0 +1,44 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class RoomSettingsErrorParser implements IMessageParser +{ + private _roomId: number; + private _code: number; + private _message: string; + + public flush(): boolean + { + this._roomId = 0; + this._code = 0; + this._message = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._roomId = wrapper.readInt(); + this._code = wrapper.readInt(); + this._message = wrapper.readString(); + + return true; + } + + public get roomId(): number + { + return this._roomId; + } + + public get code(): number + { + return this._code; + } + + public get message(): string + { + return this._message; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/room/data/RoomSettingsParser.ts b/src/nitro/communication/messages/parser/room/data/RoomSettingsParser.ts new file mode 100644 index 00000000..9c1266d2 --- /dev/null +++ b/src/nitro/communication/messages/parser/room/data/RoomSettingsParser.ts @@ -0,0 +1,163 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; +import { RoomChatParser } from './RoomChatParser'; +import { RoomModerationParser } from './RoomModerationParser'; + +export class RoomSettingsParser implements IMessageParser +{ + private _roomId: number; + private _name: string; + private _description: string; + private _state: number; + private _categoryId: number; + private _userCount: number; + private _maxUserCount: number; + private _tags: string[]; + private _tradeMode: number; + private _allowPets: number; + private _allowPetsEat: number; + private _allowWalkthrough: number; + private _hideWalls: number; + private _thicknessWall: number; + private _thicknessFloor: number; + private _chat: RoomChatParser; + private _moderation: RoomModerationParser; + + public flush(): boolean + { + this._roomId = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._roomId = wrapper.readInt(); + this._name = wrapper.readString(); + this._description = wrapper.readString(); + this._state = wrapper.readInt(); + this._categoryId = wrapper.readInt(); + this._userCount = wrapper.readInt(); + this._maxUserCount = wrapper.readInt(); + + this.parseTags(wrapper); + + this._tradeMode = wrapper.readInt(); + this._allowPets = wrapper.readInt(); + this._allowPetsEat = wrapper.readInt(); + this._allowWalkthrough = wrapper.readInt(); + this._hideWalls = wrapper.readInt(); + this._thicknessWall = wrapper.readInt(); + this._thicknessFloor = wrapper.readInt(); + this._chat = new RoomChatParser(wrapper); + wrapper.readBoolean(); + this._moderation = new RoomModerationParser(wrapper); + + return true; + } + + private parseTags(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._tags = []; + + let totalTags = wrapper.readInt(); + + while(totalTags > 0) + { + this._tags.push(wrapper.readString()); + + totalTags--; + } + + return true; + } + + public get roomId(): number + { + return this._roomId; + } + + public get name(): string + { + return this._name; + } + + public get description(): string + { + return this._description; + } + + public get state(): number + { + return this._state; + } + + public get categoryId(): number + { + return this._categoryId; + } + + public get userCount(): number + { + return this._userCount; + } + + public get maxUserCount(): number + { + return this._maxUserCount; + } + + public get tags(): string[] + { + return this._tags; + } + + public get tradeMode(): number + { + return this._tradeMode; + } + + public get allowPets(): boolean + { + return this._allowPets === 1; + } + + public get allowPetsEat(): boolean + { + return this._allowPetsEat === 1; + } + + public get allowWalkthrough(): boolean + { + return this._allowWalkthrough === 1; + } + + public get hideWalls(): boolean + { + return this._hideWalls === 1; + } + + public get thicknessWall(): number + { + return this._thicknessWall; + } + + public get thicknessFloor(): number + { + return this._thicknessFloor; + } + + public get chatSettings(): RoomChatParser + { + return this._chat; + } + + public get moderationSettings(): RoomModerationParser + { + return this._moderation; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/room/data/RoomSettingsSavedParser.ts b/src/nitro/communication/messages/parser/room/data/RoomSettingsSavedParser.ts new file mode 100644 index 00000000..bb8fee57 --- /dev/null +++ b/src/nitro/communication/messages/parser/room/data/RoomSettingsSavedParser.ts @@ -0,0 +1,28 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class RoomSettingsSavedParser implements IMessageParser +{ + private _roomId: number; + + public flush(): boolean + { + this._roomId = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._roomId = wrapper.readInt(); + + return true; + } + + public get roomId(): number + { + return this._roomId; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/room/data/RoomSettingsUpdatedParser.ts b/src/nitro/communication/messages/parser/room/data/RoomSettingsUpdatedParser.ts new file mode 100644 index 00000000..dfa8f83e --- /dev/null +++ b/src/nitro/communication/messages/parser/room/data/RoomSettingsUpdatedParser.ts @@ -0,0 +1,28 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class RoomSettingsUpdatedParser implements IMessageParser +{ + private _roomId: number; + + public flush(): boolean + { + this._roomId = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._roomId = wrapper.readInt(); + + return true; + } + + public get roomId(): number + { + return this._roomId; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/room/data/RoomSettingsUsersListParser.ts b/src/nitro/communication/messages/parser/room/data/RoomSettingsUsersListParser.ts new file mode 100644 index 00000000..a475c6df --- /dev/null +++ b/src/nitro/communication/messages/parser/room/data/RoomSettingsUsersListParser.ts @@ -0,0 +1,46 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class RoomSettingsUsersListParser implements IMessageParser +{ + private _roomId: number; + private _users: Map; + + public flush(): boolean + { + this._roomId = 0; + this._users = new Map(); + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._roomId = wrapper.readInt(); + + let usersCount = wrapper.readInt(); + + while(usersCount > 0) + { + const id = wrapper.readInt(); + const name = wrapper.readString(); + + this._users.set(id, name); + usersCount--; + } + + return true; + } + + public get roomId(): number + { + return this._roomId; + } + + public get users(): Map + { + return this._users; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/room/engine/ObjectsRollingParser.ts b/src/nitro/communication/messages/parser/room/engine/ObjectsRollingParser.ts new file mode 100644 index 00000000..4e971c31 --- /dev/null +++ b/src/nitro/communication/messages/parser/room/engine/ObjectsRollingParser.ts @@ -0,0 +1,82 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; +import { Vector3d } from '../../../../../../room/utils/Vector3d'; +import { ObjectRolling } from '../../../../../room/utils/ObjectRolling'; + +export class ObjectsRollingParser implements IMessageParser +{ + private _rollerId: number; + private _itemsRolling: ObjectRolling[]; + private _unitRolling: ObjectRolling; + + public flush(): boolean + { + this._rollerId = 0; + + this._itemsRolling = []; + this._unitRolling = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return; + + const x = wrapper.readInt(); + const y = wrapper.readInt(); + const nextX = wrapper.readInt(); + const nextY = wrapper.readInt(); + + let totalItems = wrapper.readInt(); + + while(totalItems > 0) + { + const id = wrapper.readInt(); + const height = parseFloat(wrapper.readString()); + const nextHeight = parseFloat(wrapper.readString()); + const rollingData = new ObjectRolling(id, new Vector3d(x, y, height), new Vector3d(nextX, nextY, nextHeight)); + + this._itemsRolling.push(rollingData); + + totalItems--; + } + + this._rollerId = wrapper.readInt(); + + if(!wrapper.bytesAvailable) return true; + + const movementType = wrapper.readInt(); + const unitId = wrapper.readInt(); + const height = parseFloat(wrapper.readString()); + const nextHeight = parseFloat(wrapper.readString()); + + switch(movementType) + { + case 0: break; + case 1: + this._unitRolling = new ObjectRolling(unitId, new Vector3d(x, y, height), new Vector3d(nextX, nextY, nextHeight), ObjectRolling.MOVE); + break; + case 2: + this._unitRolling = new ObjectRolling(unitId, new Vector3d(x, y, height), new Vector3d(nextX, nextY, nextHeight), ObjectRolling.SLIDE); + break; + } + + return true; + } + + public get rollerId(): number + { + return this._rollerId; + } + + public get itemsRolling(): ObjectRolling[] + { + return this._itemsRolling; + } + + public get unitRolling(): ObjectRolling + { + return this._unitRolling; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/room/engine/RoomCreatedParser.ts b/src/nitro/communication/messages/parser/room/engine/RoomCreatedParser.ts new file mode 100644 index 00000000..4e14ece8 --- /dev/null +++ b/src/nitro/communication/messages/parser/room/engine/RoomCreatedParser.ts @@ -0,0 +1,36 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class RoomCreatedParser implements IMessageParser +{ + private _roomId: number; + private _roomName: string; + + public flush(): boolean + { + this._roomId = -1; + this._roomName = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return; + + this._roomId = wrapper.readInt(); + this._roomName = wrapper.readString(); + + return true; + } + + public get roomId(): number + { + return this._roomId; + } + + public get roomName(): string + { + return this._roomName; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/room/furniture/FurnitureAliasesParser.ts b/src/nitro/communication/messages/parser/room/furniture/FurnitureAliasesParser.ts new file mode 100644 index 00000000..5ca56e53 --- /dev/null +++ b/src/nitro/communication/messages/parser/room/furniture/FurnitureAliasesParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class FurnitureAliasesParser implements IMessageParser +{ + private _aliases: Map; + + public flush(): boolean + { + this._aliases = new Map(); + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + let totalCount = wrapper.readInt(); + + while(totalCount > 0) + { + this._aliases.set(wrapper.readString(), wrapper.readString()); + + totalCount--; + } + + return true; + } + + public get aliases(): Map + { + return this._aliases; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/room/furniture/FurnitureDataParser.ts b/src/nitro/communication/messages/parser/room/furniture/FurnitureDataParser.ts new file mode 100644 index 00000000..4e996072 --- /dev/null +++ b/src/nitro/communication/messages/parser/room/furniture/FurnitureDataParser.ts @@ -0,0 +1,51 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; +import { IObjectData } from '../../../../../room/object/data/IObjectData'; +import { ObjectDataFactory } from '../../../../../room/object/data/ObjectDataFactory'; + +export class FurnitureDataParser implements IMessageParser +{ + private _itemId: number; + private _data: IObjectData; + + public flush(): boolean + { + this._itemId = 0; + this._data = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._itemId = parseInt(wrapper.readString()); + this._data = FurnitureDataParser.parseObjectData(wrapper); + + return true; + } + + public static parseObjectData(wrapper: IMessageDataWrapper): IObjectData + { + if(!wrapper) return null; + + const data = ObjectDataFactory.getData(wrapper.readInt()); + + if(!data) return null; + + data.parseWrapper(wrapper); + + return data; + } + + public get furnitureId(): number + { + return this._itemId; + } + + public get objectData(): IObjectData + { + return this._data; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/room/furniture/FurnitureItemDataParser.ts b/src/nitro/communication/messages/parser/room/furniture/FurnitureItemDataParser.ts new file mode 100644 index 00000000..6e1a1455 --- /dev/null +++ b/src/nitro/communication/messages/parser/room/furniture/FurnitureItemDataParser.ts @@ -0,0 +1,36 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class FurnitureItemDataParser implements IMessageParser +{ + private _itemId: number; + private _data: string; + + public flush(): boolean + { + this._itemId = 0; + this._data = ''; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._itemId = parseInt(wrapper.readString()); + this._data = wrapper.readString(); + + return true; + } + + public get furnitureId(): number + { + return this._itemId; + } + + public get data(): string + { + return this._data; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/room/furniture/FurnitureStackHeightParser.ts b/src/nitro/communication/messages/parser/room/furniture/FurnitureStackHeightParser.ts new file mode 100644 index 00000000..36822664 --- /dev/null +++ b/src/nitro/communication/messages/parser/room/furniture/FurnitureStackHeightParser.ts @@ -0,0 +1,36 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class FurnitureStackHeightParser implements IMessageParser +{ + private _furniId: number; + private _height: number; + + public flush(): boolean + { + this._furniId = -1; + this._height = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._furniId = wrapper.readInt(); + this._height = (wrapper.readInt() / 100); + + return true; + } + + public get furniId(): number + { + return this._furniId; + } + + public get height(): number + { + return this._height; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/room/furniture/FurnitureState2Parser.ts b/src/nitro/communication/messages/parser/room/furniture/FurnitureState2Parser.ts new file mode 100644 index 00000000..e4b342e7 --- /dev/null +++ b/src/nitro/communication/messages/parser/room/furniture/FurnitureState2Parser.ts @@ -0,0 +1,36 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class FurnitureState2Parser implements IMessageParser +{ + private _itemId: number; + private _value: number; + + public flush(): boolean + { + this._itemId = 0; + this._value = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._itemId = wrapper.readInt(); + this._value = wrapper.readInt(); + + return true; + } + + public get itemId(): number + { + return this._itemId; + } + + public get value(): number + { + return this._value; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/room/furniture/FurnitureStateParser.ts b/src/nitro/communication/messages/parser/room/furniture/FurnitureStateParser.ts new file mode 100644 index 00000000..ee8ea5a6 --- /dev/null +++ b/src/nitro/communication/messages/parser/room/furniture/FurnitureStateParser.ts @@ -0,0 +1,36 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class FurnitureStateParser implements IMessageParser +{ + private _itemId: number; + private _state: number; + + public flush(): boolean + { + this._itemId = 0; + this._state = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._itemId = wrapper.readInt(); + this._state = wrapper.readInt(); + + return true; + } + + public get itemId(): number + { + return this._itemId; + } + + public get state(): number + { + return this._state; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/room/furniture/LoveLockFurniFinishedParser.ts b/src/nitro/communication/messages/parser/room/furniture/LoveLockFurniFinishedParser.ts new file mode 100644 index 00000000..adb1875d --- /dev/null +++ b/src/nitro/communication/messages/parser/room/furniture/LoveLockFurniFinishedParser.ts @@ -0,0 +1,24 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class LoveLockFurniFinishedParser implements IMessageParser +{ + private _furniId: number; + + public get furniId(): number + { + return this._furniId; + } + + public flush(): boolean + { + this._furniId = -1; + return true; + } + + public parse(packet: IMessageDataWrapper): boolean + { + this._furniId = packet.readInt(); + return true; + } +} diff --git a/src/nitro/communication/messages/parser/room/furniture/LoveLockFurniFriendConfirmedParser.ts b/src/nitro/communication/messages/parser/room/furniture/LoveLockFurniFriendConfirmedParser.ts new file mode 100644 index 00000000..f46b9d96 --- /dev/null +++ b/src/nitro/communication/messages/parser/room/furniture/LoveLockFurniFriendConfirmedParser.ts @@ -0,0 +1,24 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class LoveLockFurniFriendConfirmedParser implements IMessageParser +{ + private _furniId: number; + + public get furniId(): number + { + return this._furniId; + } + + public flush(): boolean + { + this._furniId = -1; + return true; + } + + public parse(packet: IMessageDataWrapper): boolean + { + this._furniId = packet.readInt(); + return true; + } +} diff --git a/src/nitro/communication/messages/parser/room/furniture/LoveLockFurniStartParser.ts b/src/nitro/communication/messages/parser/room/furniture/LoveLockFurniStartParser.ts new file mode 100644 index 00000000..ea99046f --- /dev/null +++ b/src/nitro/communication/messages/parser/room/furniture/LoveLockFurniStartParser.ts @@ -0,0 +1,32 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class LoveLockFurniStartParser implements IMessageParser +{ + private _furniId: number; + private _start: boolean; + + public get furniId(): number + { + return this._furniId; + } + + public get start(): boolean + { + return this._start; + } + + public flush(): boolean + { + this._furniId = -1; + this._start = false; + return true; + } + + public parse(packet: IMessageDataWrapper): boolean + { + this._furniId = packet.readInt(); + this._start = packet.readBoolean(); + return true; + } +} diff --git a/src/nitro/communication/messages/parser/room/furniture/RoomDimmerPresetsMessageParser.ts b/src/nitro/communication/messages/parser/room/furniture/RoomDimmerPresetsMessageParser.ts new file mode 100644 index 00000000..abb8aa93 --- /dev/null +++ b/src/nitro/communication/messages/parser/room/furniture/RoomDimmerPresetsMessageParser.ts @@ -0,0 +1,70 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; +import { MoodlightFromServer } from '../../../incoming/room/furniture/moodlightFromServer'; + +export class RoomDimmerPresetsMessageParser implements IMessageParser +{ + private _selectedPresetId: number = 0; + private _presets: MoodlightFromServer[]; + + constructor() + { + this._presets = []; + } + + public get _Str_10888(): number + { + return this._presets.length; + } + + public get _Str_6226(): number + { + return this._selectedPresetId; + } + + public _Str_14989(k: number): MoodlightFromServer + { + if((k < 0) || (k >= this._Str_10888)) return null; + + return this._presets[k]; + } + + public flush(): boolean + { + this._presets = []; + + return true; + } + + public parse(k: IMessageDataWrapper): boolean + { + const totalPresets = k.readInt(); + + this._selectedPresetId = k.readInt(); + + let _local_3 = 0; + + while(_local_3 < totalPresets) + { + const presetId = k.readInt(); + const isBackGroundOnly = k.readInt(); // Background only? 2: 1 + const color = k.readString(); + const colorForSWF = parseInt(color.substr(1), 16); + const intensity = k.readInt(); + + const _local_9 = new MoodlightFromServer(presetId); + + _local_9.type = isBackGroundOnly; + _local_9.color = colorForSWF; + _local_9.intensity = intensity; + + _local_9.parsed(); + _local_9.htmlColor = color; + this._presets.push(_local_9); + + _local_3++; + } + + return true; + } +} diff --git a/src/nitro/communication/messages/parser/room/furniture/floor/FurnitureFloorAddParser.ts b/src/nitro/communication/messages/parser/room/furniture/floor/FurnitureFloorAddParser.ts new file mode 100644 index 00000000..613a969a --- /dev/null +++ b/src/nitro/communication/messages/parser/room/furniture/floor/FurnitureFloorAddParser.ts @@ -0,0 +1,30 @@ +import { IMessageDataWrapper } from '../../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../../core/communication/messages/IMessageParser'; +import { FurnitureFloorDataParser } from './FurnitureFloorDataParser'; + +export class FurnitureFloorAddParser implements IMessageParser +{ + private _item: FurnitureFloorDataParser; + + public flush(): boolean + { + this._item = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._item = new FurnitureFloorDataParser(wrapper); + this._item.username = wrapper.readString(); + + return true; + } + + public get item(): FurnitureFloorDataParser + { + return this._item; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/room/furniture/floor/FurnitureFloorDataParser.ts b/src/nitro/communication/messages/parser/room/furniture/floor/FurnitureFloorDataParser.ts new file mode 100644 index 00000000..975708d4 --- /dev/null +++ b/src/nitro/communication/messages/parser/room/furniture/floor/FurnitureFloorDataParser.ts @@ -0,0 +1,160 @@ +import { IMessageDataWrapper } from '../../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IObjectData } from '../../../../../../room/object/data/IObjectData'; +import { FurnitureDataParser } from '../FurnitureDataParser'; + +export class FurnitureFloorDataParser +{ + private _itemId: number; + private _spriteId: number; + private _spriteName: string; + private _x: number; + private _y: number; + private _direction: number; + private _z: number; + private _stackHeight: number; + private _extra: number; + private _data: IObjectData; + private _state: number; + private _expires: number; + private _usagePolicy: number; + private _userId: number; + private _username: string; + + constructor(wrapper: IMessageDataWrapper) + { + if(!wrapper) throw new Error('invalid_wrapper'); + + this.flush(); + this.parse(wrapper); + } + + public flush(): boolean + { + this._itemId = 0; + this._spriteId = 0; + this._spriteName = null; + this._x = 0; + this._y = 0; + this._direction = 0; + this._z = 0; + this._stackHeight = 0; + this._extra = 0; + this._data = null; + this._state = 0; + this._expires = 0; + this._usagePolicy = 0; + this._userId = 0; + this._username = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._itemId = wrapper.readInt(); + this._spriteId = wrapper.readInt(); + this._x = wrapper.readInt(); + this._y = wrapper.readInt(); + this._direction = ((wrapper.readInt() % 8) * 45); + this._z = parseFloat(wrapper.readString()); + this._stackHeight = parseFloat(wrapper.readString()); + this._extra = wrapper.readInt(); + this._data = FurnitureDataParser.parseObjectData(wrapper); + this._state = parseFloat(this._data && this._data.getLegacyString()) || 0; + this._expires = wrapper.readInt(); + this._usagePolicy = wrapper.readInt(); + this._userId = wrapper.readInt(); + this._username = null; + + if(this._spriteId < 0) this._spriteName = wrapper.readString(); + + return true; + } + + public get itemId(): number + { + return this._itemId; + } + + public get spriteId(): number + { + return this._spriteId; + } + + public get x(): number + { + return this._x; + } + + public get y(): number + { + return this._y; + } + + public get direction(): number + { + return this._direction; + } + + public get z(): number + { + return ((isNaN(this._z)) ? 0 : this._z); + } + + public get stackHeight(): number + { + return ((isNaN(this._stackHeight)) ? 0 : this._stackHeight); + } + + public get extra(): number + { + return this._extra; + } + + public get data(): IObjectData + { + return this._data; + } + + public get state(): number + { + return this._state; + } + + public get expires(): number + { + return this._expires; + } + + public get usagePolicy(): number + { + return this._usagePolicy; + } + + public get userId(): number + { + return this._userId; + } + + public get username(): string + { + return this._username; + } + + public set username(username: string) + { + this._username = username; + } + + public get spriteName(): string + { + return this._spriteName; + } + + public set spriteName(type: string) + { + this._spriteName = type; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/room/furniture/floor/FurnitureFloorParser.ts b/src/nitro/communication/messages/parser/room/furniture/floor/FurnitureFloorParser.ts new file mode 100644 index 00000000..b892f4d1 --- /dev/null +++ b/src/nitro/communication/messages/parser/room/furniture/floor/FurnitureFloorParser.ts @@ -0,0 +1,69 @@ +import { IMessageDataWrapper } from '../../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../../core/communication/messages/IMessageParser'; +import { FurnitureFloorDataParser } from './FurnitureFloorDataParser'; + +export class FurnitureFloorParser implements IMessageParser +{ + private _owners: Map; + private _items: FurnitureFloorDataParser[]; + + public flush(): boolean + { + this._owners = new Map(); + this._items = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + if(!this.parseOwners(wrapper)) return false; + + let totalItems = wrapper.readInt(); + + while(totalItems > 0) + { + const item = new FurnitureFloorDataParser(wrapper); + + if(!item) continue; + + const username = this._owners.get(item.userId); + + if(username) item.username = username; + + this._items.push(item); + + totalItems--; + } + + return true; + } + + private parseOwners(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + let totalOwners = wrapper.readInt(); + + while(totalOwners > 0) + { + this._owners.set(wrapper.readInt(), wrapper.readString()); + + totalOwners--; + } + + return true; + } + + public get owners(): Map + { + return this._owners; + } + + public get items(): FurnitureFloorDataParser[] + { + return this._items; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/room/furniture/floor/FurnitureFloorRemoveParser.ts b/src/nitro/communication/messages/parser/room/furniture/floor/FurnitureFloorRemoveParser.ts new file mode 100644 index 00000000..a99a160d --- /dev/null +++ b/src/nitro/communication/messages/parser/room/furniture/floor/FurnitureFloorRemoveParser.ts @@ -0,0 +1,52 @@ +import { IMessageDataWrapper } from '../../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../../core/communication/messages/IMessageParser'; + +export class FurnitureFloorRemoveParser implements IMessageParser +{ + private _itemId: number; + private _isExpired: boolean; + private _userId: number; + private _delay: number; + + public flush(): boolean + { + this._itemId = 0; + this._isExpired = true; + this._userId = 0; + this._delay = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._itemId = parseInt(wrapper.readString()); + this._isExpired = wrapper.readBoolean(); + this._userId = wrapper.readInt(); + this._delay = wrapper.readInt(); + + return true; + } + + public get itemId(): number + { + return this._itemId; + } + + public get isExpired(): boolean + { + return this._isExpired; + } + + public get userId(): number + { + return this._userId; + } + + public get delay(): number + { + return this._delay; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/room/furniture/floor/FurnitureFloorUpdateParser.ts b/src/nitro/communication/messages/parser/room/furniture/floor/FurnitureFloorUpdateParser.ts new file mode 100644 index 00000000..8f3e57af --- /dev/null +++ b/src/nitro/communication/messages/parser/room/furniture/floor/FurnitureFloorUpdateParser.ts @@ -0,0 +1,29 @@ +import { IMessageDataWrapper } from '../../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../../core/communication/messages/IMessageParser'; +import { FurnitureFloorDataParser } from './FurnitureFloorDataParser'; + +export class FurnitureFloorUpdateParser implements IMessageParser +{ + private _item: FurnitureFloorDataParser; + + public flush(): boolean + { + this._item = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._item = new FurnitureFloorDataParser(wrapper); + + return true; + } + + public get item(): FurnitureFloorDataParser + { + return this._item; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/room/furniture/wall/FurnitureWallAddParser.ts b/src/nitro/communication/messages/parser/room/furniture/wall/FurnitureWallAddParser.ts new file mode 100644 index 00000000..ebad7846 --- /dev/null +++ b/src/nitro/communication/messages/parser/room/furniture/wall/FurnitureWallAddParser.ts @@ -0,0 +1,30 @@ +import { IMessageDataWrapper } from '../../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../../core/communication/messages/IMessageParser'; +import { FurnitureWallDataParser } from './FurnitureWallDataParser'; + +export class FurnitureWallAddParser implements IMessageParser +{ + private _item: FurnitureWallDataParser; + + public flush(): boolean + { + this._item = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._item = new FurnitureWallDataParser(wrapper); + this._item.username = wrapper.readString(); + + return true; + } + + public get item(): FurnitureWallDataParser + { + return this._item; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/room/furniture/wall/FurnitureWallDataParser.ts b/src/nitro/communication/messages/parser/room/furniture/wall/FurnitureWallDataParser.ts new file mode 100644 index 00000000..cbcf5a0b --- /dev/null +++ b/src/nitro/communication/messages/parser/room/furniture/wall/FurnitureWallDataParser.ts @@ -0,0 +1,228 @@ +import { IMessageDataWrapper } from '../../../../../../../core/communication/messages/IMessageDataWrapper'; + +export class FurnitureWallDataParser +{ + private _itemId: number; + private _spriteId: number; + private _location: string; + private _stuffData: string; + private _state: number; + private _secondsToExpiration: number; + private _usagePolicy: number; + private _userId: number; + private _username: string; + + private _width: number; + private _height: number; + private _localX: number; + private _localY: number; + private _y: number; + private _z: number; + private _direction: string; + private _Str_19875: boolean; + + constructor(wrapper: IMessageDataWrapper) + { + if(!wrapper) throw new Error('invalid_wrapper'); + + this.flush(); + this.parse(wrapper); + } + + public flush(): boolean + { + this._itemId = 0; + this._spriteId = 0; + this._location = null; + this._stuffData = null; + this._state = 0; + this._secondsToExpiration = 0; + this._usagePolicy = -1; + this._userId = 0; + this._username = null; + + this._width = 0; + this._height = 0; + this._localX = 0; + this._localY = 0; + this._y = 0; + this._z = 0; + this._direction = null; + this._Str_19875 = false; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._itemId = parseInt(wrapper.readString()); + this._spriteId = wrapper.readInt(); + this._location = wrapper.readString(); + this._stuffData = wrapper.readString(); + this._secondsToExpiration = wrapper.readInt(); + this._usagePolicy = wrapper.readInt(); + this._userId = wrapper.readInt(); + this._username = null; + + const state = parseFloat(this._stuffData); + + if(!isNaN(state)) this._state = state; + + if(this._location.indexOf(':') === 0) + { + this._Str_19875 = false; + + let parts = this._location.split(' '); + + if(parts.length >= 3) + { + let widthHeight = parts[0]; + let leftRight = parts[1]; + + const direction = parts[2]; + + if((widthHeight.length > 3) && (leftRight.length > 2)) + { + widthHeight = widthHeight.substr(3); + leftRight = leftRight.substr(2); + parts = widthHeight.split(','); + + if(parts.length >= 2) + { + const width = parseInt(parts[0]); + const height = parseInt(parts[1]); + + parts = leftRight.split(','); + + if(parts.length >= 2) + { + const localX = parseInt(parts[0]); + const localY = parseInt(parts[1]); + + this._width = width; + this._height = height; + this._localX = localX; + this._localY = localY; + this._direction = direction; + } + } + } + } + } + else + { + this._Str_19875 = true; + + // _local_12 = _local_4.split(" "); + // if (_local_12.length >= 2) + // { + // _local_13 = String(_local_12[0]); + // if (((_local_13 == "rightwall") || (_local_13 == "frontwall"))) + // { + // _local_13 = "r"; + // } + // else + // { + // _local_13 = "l"; + // } + // _local_20 = String(_local_12[1]); + // _local_21 = _local_20.split(","); + // if (_local_21.length >= 3) + // { + // _local_22 = 0; + // _local_23 = parseFloat(_local_21[0]); + // _local_24 = parseFloat(_local_21[1]); + // _local_11.y = _local_23; + // _local_11.z = _local_24; + // _local_11.dir = _local_13; + // _local_11.data = _local_5; + // _local_11.state = _local_9; + // } + // } + } + + return true; + } + + public get itemId(): number + { + return this._itemId; + } + + public get spriteId(): number + { + return this._spriteId; + } + + public get wallPosition(): string + { + return this._location; + } + + public get stuffData(): string + { + return this._stuffData; + } + + public get state(): number + { + return this._state; + } + + public get secondsToExpiration(): number + { + return this._secondsToExpiration; + } + + public get usagePolicy(): number + { + return this._usagePolicy; + } + + public get userId(): number + { + return this._userId; + } + + public get username(): string + { + return this._username; + } + + public set username(username: string) + { + this._username = username; + } + + public get width(): number + { + return this._width; + } + + public get height(): number + { + return this._height; + } + + public get localX(): number + { + return this._localX; + } + + public get localY(): number + { + return this._localY; + } + + public get direction(): string + { + return this._direction; + } + + public get _Str_22379(): boolean + { + return this._Str_19875; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/room/furniture/wall/FurnitureWallParser.ts b/src/nitro/communication/messages/parser/room/furniture/wall/FurnitureWallParser.ts new file mode 100644 index 00000000..94f78286 --- /dev/null +++ b/src/nitro/communication/messages/parser/room/furniture/wall/FurnitureWallParser.ts @@ -0,0 +1,69 @@ +import { IMessageDataWrapper } from '../../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../../core/communication/messages/IMessageParser'; +import { FurnitureWallDataParser } from './FurnitureWallDataParser'; + +export class FurnitureWallParser implements IMessageParser +{ + private _owners: Map; + private _items: FurnitureWallDataParser[]; + + public flush(): boolean + { + this._owners = new Map(); + this._items = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + if(!this.parseOwners(wrapper)) return false; + + let totalItems = wrapper.readInt(); + + while(totalItems > 0) + { + const item = new FurnitureWallDataParser(wrapper); + + if(!item) continue; + + const username = this._owners.get(item.userId); + + if(username) item.username = username; + + this._items.push(item); + + totalItems--; + } + + return true; + } + + private parseOwners(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + let totalOwners = wrapper.readInt(); + + while(totalOwners > 0) + { + this._owners.set(wrapper.readInt(), wrapper.readString()); + + totalOwners--; + } + + return true; + } + + public get owners(): Map + { + return this._owners; + } + + public get items(): FurnitureWallDataParser[] + { + return this._items; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/room/furniture/wall/FurnitureWallRemoveParser.ts b/src/nitro/communication/messages/parser/room/furniture/wall/FurnitureWallRemoveParser.ts new file mode 100644 index 00000000..a441141f --- /dev/null +++ b/src/nitro/communication/messages/parser/room/furniture/wall/FurnitureWallRemoveParser.ts @@ -0,0 +1,36 @@ +import { IMessageDataWrapper } from '../../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../../core/communication/messages/IMessageParser'; + +export class FurnitureWallRemoveParser implements IMessageParser +{ + private _itemId: number; + private _userId: number; + + public flush(): boolean + { + this._itemId = 0; + this._userId = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._itemId = parseInt(wrapper.readString()); + this._userId = wrapper.readInt(); + + return true; + } + + public get itemId(): number + { + return this._itemId; + } + + public get userId(): number + { + return this._userId; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/room/furniture/wall/FurnitureWallUpdateParser.ts b/src/nitro/communication/messages/parser/room/furniture/wall/FurnitureWallUpdateParser.ts new file mode 100644 index 00000000..11ea7d14 --- /dev/null +++ b/src/nitro/communication/messages/parser/room/furniture/wall/FurnitureWallUpdateParser.ts @@ -0,0 +1,30 @@ +import { IMessageDataWrapper } from '../../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../../core/communication/messages/IMessageParser'; +import { FurnitureWallDataParser } from './FurnitureWallDataParser'; + +export class FurnitureWallUpdateParser implements IMessageParser +{ + private _item: FurnitureWallDataParser; + + public flush(): boolean + { + this._item = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._item = new FurnitureWallDataParser(wrapper); + this._item.username = wrapper.readString(); + + return true; + } + + public get item(): FurnitureWallDataParser + { + return this._item; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/room/mapping/RoomDoorParser.ts b/src/nitro/communication/messages/parser/room/mapping/RoomDoorParser.ts new file mode 100644 index 00000000..3df38b3c --- /dev/null +++ b/src/nitro/communication/messages/parser/room/mapping/RoomDoorParser.ts @@ -0,0 +1,44 @@ +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; + +export class RoomDoorParser implements IMessageParser +{ + private _x: number; + private _y: number; + private _direction: number; + + public flush(): boolean + { + this._x = 0; + this._y = 0; + this._direction = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._x = wrapper.readInt(); + this._y = wrapper.readInt(); + this._direction = wrapper.readInt(); + + return true; + } + + public get x(): number + { + return this._x; + } + + public get y(): number + { + return this._y; + } + + public get direction(): number + { + return this._direction; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/room/mapping/RoomHeightMapParser.ts b/src/nitro/communication/messages/parser/room/mapping/RoomHeightMapParser.ts new file mode 100644 index 00000000..0baf15c0 --- /dev/null +++ b/src/nitro/communication/messages/parser/room/mapping/RoomHeightMapParser.ts @@ -0,0 +1,89 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class RoomHeightMapParser implements IMessageParser +{ + private _width: number; + private _height: number; + private _heights: number[]; + + public static decodeTileHeight(height: number): number + { + return ((height < 0) ? -1 : ((height & 16383) / 0x0100)); + } + + public static decodeIsStackingBlocked(height: number): boolean + { + return !!(height & 0x4000); + } + + public static decodeIsRoomTile(height: number): boolean + { + return height >= 0; + } + + public getTileHeight(x: number, y: number): number + { + if((x < 0) || (x >= this._width) || (y < 0) || (y >= this._height)) return -1; + + return RoomHeightMapParser.decodeTileHeight(this._heights[((y * this._width) + x)]); + } + + public getStackingBlocked(x: number, y: number): boolean + { + if((x < 0) || (x >= this._width) || (y < 0) || (y >= this._height)) return true; + + return RoomHeightMapParser.decodeIsStackingBlocked(this._heights[((y * this._width) + x)]); + } + + public isRoomTile(x: number, y: number): boolean + { + if((x < 0) || (x >= this._width) || (y < 0) || (y >= this._height)) return false; + + return RoomHeightMapParser.decodeIsRoomTile(this._heights[((y * this._width) + x)]); + } + + public flush(): boolean + { + this._width = 0; + this._height = 0; + this._heights = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._width = wrapper.readInt(); + const totalTiles = wrapper.readInt(); + this._height = totalTiles / this._width; + + let i = 0; + + while(i < totalTiles) + { + this._heights[i] = wrapper.readShort(); + + i++; + } + + return true; + } + + public get width(): number + { + return this._width; + } + + public get height(): number + { + return this._height; + } + + public get heights(): number[] + { + return this._heights; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/room/mapping/RoomHeightMapUpdateParser.ts b/src/nitro/communication/messages/parser/room/mapping/RoomHeightMapUpdateParser.ts new file mode 100644 index 00000000..8da1e045 --- /dev/null +++ b/src/nitro/communication/messages/parser/room/mapping/RoomHeightMapUpdateParser.ts @@ -0,0 +1,76 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; +import { RoomHeightMapParser } from './RoomHeightMapParser'; + +export class RoomHeightMapUpdateParser implements IMessageParser +{ + private _wrapper: IMessageDataWrapper; + private _count: number; + private _x: number; + private _y: number; + private _value: number; + + public flush(): boolean + { + this._wrapper = null; + this._count = 0; + this._x = 0; + this._y = 0; + this._value = 0; + + return true; + } + + public tileHeight(): number + { + return RoomHeightMapParser.decodeTileHeight(this._value); + } + + public isStackingBlocked(): boolean + { + return RoomHeightMapParser.decodeIsStackingBlocked(this._value); + } + + public isRoomTile(): boolean + { + return RoomHeightMapParser.decodeIsRoomTile(this._value); + } + + public next(): boolean + { + if(!this._count) return false; + + this._count--; + + this._x = this._wrapper.readByte(); + this._y = this._wrapper.readByte(); + this._value = this._wrapper.readShort(); + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._wrapper = wrapper; + this._count = wrapper.readByte(); + + return true; + } + + public get x(): number + { + return this._x; + } + + public get y(): number + { + return this._y; + } + + public get height(): number + { + return this._value; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/room/mapping/RoomModelNameParser.ts b/src/nitro/communication/messages/parser/room/mapping/RoomModelNameParser.ts new file mode 100644 index 00000000..bf062350 --- /dev/null +++ b/src/nitro/communication/messages/parser/room/mapping/RoomModelNameParser.ts @@ -0,0 +1,36 @@ +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; + +export class RoomModelNameParser implements IMessageParser +{ + private _name: string; + private _roomId: number; + + public flush(): boolean + { + this._name = null; + this._roomId = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._name = wrapper.readString(); + this._roomId = wrapper.readInt(); + + return true; + } + + public get name(): string + { + return this._name; + } + + public get roomId(): number + { + return this._roomId; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/room/mapping/RoomModelParser.ts b/src/nitro/communication/messages/parser/room/mapping/RoomModelParser.ts new file mode 100644 index 00000000..1679d418 --- /dev/null +++ b/src/nitro/communication/messages/parser/room/mapping/RoomModelParser.ts @@ -0,0 +1,167 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; +import { RoomPlaneParser } from '../../../../../room/object/RoomPlaneParser'; + +export class RoomModelParser implements IMessageParser +{ + private _model: string; + private _width: number; + private _height: number; + private _heightMap: number[][]; + private _wallHeight: number; + private _scale: number; + + public flush(): boolean + { + this._model = null; + this._width = 0; + this._height = 0; + this._wallHeight = -1; + this._heightMap = []; + this._scale = 64; + this._model = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + const scale = wrapper.readBoolean(); + const wallHeight = wrapper.readInt(); + const model = wrapper.readString(); + + return this.parseExplicitly(model, wallHeight, scale); + } + + public parseModel(modelString: string, wallHeight: number, scale: boolean = true): boolean + { + return this.parseExplicitly(modelString, wallHeight, scale); + } + + private parseExplicitly(modelString: string, wallHeight: number, scale: boolean = true): boolean + { + this._scale = scale ? 32 : 64; + this._wallHeight = wallHeight; + this._model = modelString; + + const model = this._model.split('\r'); + const modelRows = model.length; + + let width = 0; + const height = 0; + + let iterator = 0; + + while(iterator < modelRows) + { + const row = model[iterator]; + + if(row.length > width) + { + width = row.length; + } + + iterator++; + } + + this._heightMap = []; + iterator = 0; + + while(iterator < modelRows) + { + const heightMap: number[] = []; + + let subIterator = 0; + + while(subIterator < width) + { + heightMap.push(RoomPlaneParser.TILE_BLOCKED); + + subIterator++; + } + + this._heightMap.push(heightMap); + + iterator++; + } + + this._width = width; + this._height = modelRows; + + iterator = 0; + + while(iterator < modelRows) + { + const heightMap = this._heightMap[iterator]; + const text = model[iterator]; + + if(text.length > 0) + { + let subIterator = 0; + + while(subIterator < text.length) + { + const char = text.charAt(subIterator); + let height = RoomPlaneParser.TILE_BLOCKED; + + if((char !== 'x') && (char !== 'X')) height = parseInt(char, 36); + + heightMap[subIterator] = height; + + subIterator++; + } + } + + iterator++; + } + + return true; + } + + public getHeight(x: number, y: number): number + { + if((x < 0) || (x >= this._width) || (y < 0) || (y >= this._height)) return -110; + + const row = this._heightMap[y]; + + if(row === undefined) return -110; + + const height = row[x]; + + if(height === undefined) return -110; + + return height; + } + + public get model(): string + { + return this._model; + } + + public get width(): number + { + return this._width; + } + + public get height(): number + { + return this._height; + } + + public get heightMap(): number[][] + { + return this._heightMap; + } + + public get wallHeight(): number + { + return this._wallHeight; + } + + public get scale(): number + { + return this._scale; + } +} diff --git a/src/nitro/communication/messages/parser/room/mapping/RoomPaintParser.ts b/src/nitro/communication/messages/parser/room/mapping/RoomPaintParser.ts new file mode 100644 index 00000000..5a68b09c --- /dev/null +++ b/src/nitro/communication/messages/parser/room/mapping/RoomPaintParser.ts @@ -0,0 +1,66 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class RoomPaintParser implements IMessageParser +{ + private _floorType: string; + private _wallType: string; + private _landscapeType: string; + private _landscapeAnimation: string; + + public flush(): boolean + { + this._floorType = null; + this._wallType = null; + this._landscapeType = null; + this._landscapeAnimation = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + const type = wrapper.readString(); + const value = wrapper.readString(); + + switch(type) + { + case 'floor': + this._floorType = value; + break; + case 'wallpaper': + this._wallType = value; + break; + case 'landscape': + this._landscapeType = value; + break; + case 'landscapeanim': + this._landscapeAnimation = value; + break; + } + + return true; + } + + public get floorType(): string + { + return this._floorType; + } + + public get wallType(): string + { + return this._wallType; + } + + public get landscapeType(): string + { + return this._landscapeType; + } + + public get landscapeAnimation(): string + { + return this._landscapeAnimation; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/room/mapping/RoomThicknessParser.ts b/src/nitro/communication/messages/parser/room/mapping/RoomThicknessParser.ts new file mode 100644 index 00000000..2e47c600 --- /dev/null +++ b/src/nitro/communication/messages/parser/room/mapping/RoomThicknessParser.ts @@ -0,0 +1,51 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class RoomThicknessParser implements IMessageParser +{ + private _hideWalls: boolean; + private _thicknessWall: number; + private _thicknessFloor: number; + + public flush(): boolean + { + this._hideWalls = false; + this._thicknessWall = 0; + this._thicknessFloor = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._hideWalls = wrapper.readBoolean(); + + let thicknessWall = wrapper.readInt(); + let thicknessFloor = wrapper.readInt(); + + thicknessWall = (thicknessWall < -2) ? -2 : (thicknessWall > 1) ? 1 : thicknessWall; + thicknessFloor = (thicknessFloor < -2) ? -2 : (thicknessFloor > 1) ? 1 : thicknessFloor; + + this._thicknessWall = Math.pow(2, thicknessWall); + this._thicknessFloor = Math.pow(2, thicknessFloor); + + return true; + } + + public get hideWalls(): boolean + { + return this._hideWalls; + } + + public get thicknessWall(): number + { + return this._thicknessWall; + } + + public get thicknessFloor(): number + { + return this._thicknessFloor; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/room/pet/PetFigureUpdateParser.ts b/src/nitro/communication/messages/parser/room/pet/PetFigureUpdateParser.ts new file mode 100644 index 00000000..e6918ea7 --- /dev/null +++ b/src/nitro/communication/messages/parser/room/pet/PetFigureUpdateParser.ts @@ -0,0 +1,55 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; +import { PetFigureData } from '../../inventory/pets/PetFigureData'; + +export class PetFigureUpdateParser implements IMessageParser +{ + private _roomIndex: number; + private _petId: number; + private _figureData: PetFigureData; + private _hasSaddle: boolean; + private _isRiding: boolean; + + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._roomIndex = wrapper.readInt(); + this._petId = wrapper.readInt(); + this._figureData = new PetFigureData(wrapper); + this._hasSaddle = wrapper.readBoolean(); + this._isRiding = wrapper.readBoolean(); + + return true; + } + + public get roomIndex(): number + { + return this._roomIndex; + } + + public get petId(): number + { + return this._petId; + } + + public get figureData(): PetFigureData + { + return this._figureData; + } + + public get hasSaddle(): boolean + { + return this._hasSaddle; + } + + public get isRiding(): boolean + { + return this._isRiding; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/room/pet/PetInfoParser.ts b/src/nitro/communication/messages/parser/room/pet/PetInfoParser.ts new file mode 100644 index 00000000..8c088687 --- /dev/null +++ b/src/nitro/communication/messages/parser/room/pet/PetInfoParser.ts @@ -0,0 +1,221 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class PetInfoParser implements IMessageParser +{ + private _id: number; + private _name: string; + private _level: number; + private _maximumLevel: number; + private _experience: number; + private _energy: number; + private _happyness: number; + private _levelExperienceGoal: number; + private _maximumEnergy: number; + private _maximumHappyness: number; + private _respect: number; + private _ownerId: number; + private _ownerName: string; + private _age: number; + private _rarityLevel: number; + private _saddle: boolean; + private _rider: boolean; + private _breedable: boolean; + private _fullyGrown: boolean; + private _dead: boolean; + private _maximumTimeToLive: number; + private _remainingTimeToLive: number; + private _remainingGrowTime: number; + private _Str_4460: number[]; + private _publiclyRideable: number; + private _unknownRarity: number; + private _publiclyBreedable: boolean; + + public flush(): boolean + { + this._id = -1; + this._Str_4460 = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._id = wrapper.readInt(); + this._name = wrapper.readString(); + this._level = wrapper.readInt(); + this._maximumLevel = wrapper.readInt(); + this._experience = wrapper.readInt(); + this._levelExperienceGoal = wrapper.readInt(); + this._energy = wrapper.readInt(); + this._maximumEnergy = wrapper.readInt(); + this._happyness = wrapper.readInt(); + this._maximumHappyness = wrapper.readInt(); + this._respect = wrapper.readInt(); + this._ownerId = wrapper.readInt(); + this._age = wrapper.readInt(); + this._ownerName = wrapper.readString(); + this._rarityLevel = wrapper.readInt(); + this._saddle = wrapper.readBoolean(); + this._rider = wrapper.readBoolean(); + + let total = wrapper.readInt(); + + while(total > 0) + { + this._Str_4460.push(wrapper.readInt()); + + total--; + } + + this._Str_4460.sort(); + this._publiclyRideable = wrapper.readInt(); + this._breedable = wrapper.readBoolean(); + this._fullyGrown = wrapper.readBoolean(); + this._dead = wrapper.readBoolean(); + this._unknownRarity = wrapper.readInt(); + this._maximumTimeToLive = wrapper.readInt(); + this._remainingTimeToLive = wrapper.readInt(); + this._remainingGrowTime = wrapper.readInt(); + this._publiclyBreedable = wrapper.readBoolean(); + + return true; + } + + public get id(): number + { + return this._id; + } + + public get name(): string + { + return this._name; + } + + public get level(): number + { + return this._level; + } + + public get maximumLevel(): number + { + return this._maximumLevel; + } + + public get experience(): number + { + return this._experience; + } + + public get energy(): number + { + return this._energy; + } + + public get happyness(): number + { + return this._happyness; + } + + public get levelExperienceGoal(): number + { + return this._levelExperienceGoal; + } + + public get maximumEnergy(): number + { + return this._maximumEnergy; + } + + public get maximumHappyness(): number + { + return this._maximumHappyness; + } + + public get respect(): number + { + return this._respect; + } + + public get ownerId(): number + { + return this._ownerId; + } + + public get ownerName(): string + { + return this._ownerName; + } + + public get age(): number + { + return this._age; + } + + public get rarityLevel(): number + { + return this._rarityLevel; + } + + public get saddle(): boolean + { + return this._saddle; + } + + public get rider(): boolean + { + return this._rider; + } + + public get breedable(): boolean + { + return this._breedable; + } + + public get fullyGrown(): boolean + { + return this._fullyGrown; + } + + public get dead(): boolean + { + return this._dead; + } + + public get maximumTimeToLive(): number + { + return this._maximumTimeToLive; + } + + public get remainingTimeToLive(): number + { + return this._remainingTimeToLive; + } + + public get remainingGrowTime(): number + { + return this._remainingGrowTime; + } + + public get _Str_3307(): number[] + { + return this._Str_4460; + } + + public get publiclyRideable(): number + { + return this._publiclyRideable; + } + + public get unknownRarity(): number + { + return this._unknownRarity; + } + + public get publiclyBreedable(): boolean + { + return this._publiclyBreedable; + } +} diff --git a/src/nitro/communication/messages/parser/room/session/YouArePlayingGameParser.ts b/src/nitro/communication/messages/parser/room/session/YouArePlayingGameParser.ts new file mode 100644 index 00000000..92abf519 --- /dev/null +++ b/src/nitro/communication/messages/parser/room/session/YouArePlayingGameParser.ts @@ -0,0 +1,28 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class YouArePlayingGameParser implements IMessageParser +{ + private _isPlaying: boolean; + + public flush(): boolean + { + this._isPlaying = false; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._isPlaying = wrapper.readBoolean(); + + return true; + } + + public get isPlaying(): boolean + { + return this._isPlaying; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/room/unit/RoomUnitDanceParser.ts b/src/nitro/communication/messages/parser/room/unit/RoomUnitDanceParser.ts new file mode 100644 index 00000000..bc475217 --- /dev/null +++ b/src/nitro/communication/messages/parser/room/unit/RoomUnitDanceParser.ts @@ -0,0 +1,36 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class RoomUnitDanceParser implements IMessageParser +{ + private _unitId: number; + private _danceId: number; + + public flush(): boolean + { + this._unitId = null; + this._danceId = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._unitId = wrapper.readInt(); + this._danceId = wrapper.readInt(); + + return true; + } + + public get unitId(): number + { + return this._unitId; + } + + public get danceId(): number + { + return this._danceId; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/room/unit/RoomUnitEffectParser.ts b/src/nitro/communication/messages/parser/room/unit/RoomUnitEffectParser.ts new file mode 100644 index 00000000..9f8357e7 --- /dev/null +++ b/src/nitro/communication/messages/parser/room/unit/RoomUnitEffectParser.ts @@ -0,0 +1,44 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class RoomUnitEffectParser implements IMessageParser +{ + private _unitId: number; + private _effectId: number; + private _delay: number; + + public flush(): boolean + { + this._unitId = null; + this._effectId = 0; + this._delay = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._unitId = wrapper.readInt(); + this._effectId = wrapper.readInt(); + this._delay = wrapper.readInt(); + + return true; + } + + public get unitId(): number + { + return this._unitId; + } + + public get effectId(): number + { + return this._effectId; + } + + public get delay(): number + { + return this._delay; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/room/unit/RoomUnitExpressionParser.ts b/src/nitro/communication/messages/parser/room/unit/RoomUnitExpressionParser.ts new file mode 100644 index 00000000..30adb015 --- /dev/null +++ b/src/nitro/communication/messages/parser/room/unit/RoomUnitExpressionParser.ts @@ -0,0 +1,36 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class RoomUnitExpressionParser implements IMessageParser +{ + private _unitId: number; + private _expression: number; + + public flush(): boolean + { + this._unitId = null; + this._expression = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._unitId = wrapper.readInt(); + this._expression = wrapper.readInt(); + + return true; + } + + public get unitId(): number + { + return this._unitId; + } + + public get expression(): number + { + return this._expression; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/room/unit/RoomUnitHandItemParser.ts b/src/nitro/communication/messages/parser/room/unit/RoomUnitHandItemParser.ts new file mode 100644 index 00000000..4133af60 --- /dev/null +++ b/src/nitro/communication/messages/parser/room/unit/RoomUnitHandItemParser.ts @@ -0,0 +1,36 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class RoomUnitHandItemParser implements IMessageParser +{ + private _unitId: number; + private _handId: number; + + public flush(): boolean + { + this._unitId = null; + this._handId = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._unitId = wrapper.readInt(); + this._handId = wrapper.readInt(); + + return true; + } + + public get unitId(): number + { + return this._unitId; + } + + public get handId(): number + { + return this._handId; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/room/unit/RoomUnitHandItemReceivedParser.ts b/src/nitro/communication/messages/parser/room/unit/RoomUnitHandItemReceivedParser.ts new file mode 100644 index 00000000..ad60ef2e --- /dev/null +++ b/src/nitro/communication/messages/parser/room/unit/RoomUnitHandItemReceivedParser.ts @@ -0,0 +1,36 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class RoomUnitHandItemReceivedParser implements IMessageParser +{ + private _giverUserId: number; + private _handItemType: number; + + public flush(): boolean + { + this._giverUserId = -1; + this._handItemType = -1; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._giverUserId = wrapper.readInt(); + this._handItemType = wrapper.readInt(); + + return true; + } + + public get giverUserId(): number + { + return this._giverUserId; + } + + public get handItemType(): number + { + return this._handItemType; + } +} diff --git a/src/nitro/communication/messages/parser/room/unit/RoomUnitIdleParser.ts b/src/nitro/communication/messages/parser/room/unit/RoomUnitIdleParser.ts new file mode 100644 index 00000000..f0b288a1 --- /dev/null +++ b/src/nitro/communication/messages/parser/room/unit/RoomUnitIdleParser.ts @@ -0,0 +1,36 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class RoomUnitIdleParser implements IMessageParser +{ + private _unitId: number; + private _isIdle: boolean; + + public flush(): boolean + { + this._unitId = null; + this._isIdle = false; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._unitId = wrapper.readInt(); + this._isIdle = wrapper.readBoolean(); + + return true; + } + + public get unitId(): number + { + return this._unitId; + } + + public get isIdle(): boolean + { + return this._isIdle; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/room/unit/RoomUnitInfoParser.ts b/src/nitro/communication/messages/parser/room/unit/RoomUnitInfoParser.ts new file mode 100644 index 00000000..66e198f1 --- /dev/null +++ b/src/nitro/communication/messages/parser/room/unit/RoomUnitInfoParser.ts @@ -0,0 +1,60 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class RoomUnitInfoParser implements IMessageParser +{ + private _unitId: number; + private _figure: string; + private _gender: string; + private _motto: string; + private _achievementScore: number; + + public flush(): boolean + { + this._unitId = null; + this._figure = null; + this._gender = 'M'; + this._motto = null; + this._achievementScore = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._unitId = wrapper.readInt(); + this._figure = wrapper.readString(); + this._gender = wrapper.readString().toLocaleUpperCase(); + this._motto = wrapper.readString(); + this._achievementScore = wrapper.readInt(); + + return true; + } + + public get unitId(): number + { + return this._unitId; + } + + public get figure(): string + { + return this._figure; + } + + public get gender(): string + { + return this._gender; + } + + public get motto(): string + { + return this._motto; + } + + public get achievementScore(): number + { + return this._achievementScore; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/room/unit/RoomUnitNumberParser.ts b/src/nitro/communication/messages/parser/room/unit/RoomUnitNumberParser.ts new file mode 100644 index 00000000..ca061e08 --- /dev/null +++ b/src/nitro/communication/messages/parser/room/unit/RoomUnitNumberParser.ts @@ -0,0 +1,36 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class RoomUnitNumberParser implements IMessageParser +{ + private _unitId: number; + private _value: number; + + public flush(): boolean + { + this._unitId = null; + this._value = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._unitId = wrapper.readInt(); + this._value = wrapper.readInt(); + + return true; + } + + public get unitId(): number + { + return this._unitId; + } + + public get value(): number + { + return this._value; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/room/unit/RoomUnitParser.ts b/src/nitro/communication/messages/parser/room/unit/RoomUnitParser.ts new file mode 100644 index 00000000..2c9cdde7 --- /dev/null +++ b/src/nitro/communication/messages/parser/room/unit/RoomUnitParser.ts @@ -0,0 +1,188 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; +import { RoomObjectType } from '../../../../../room/object/RoomObjectType'; +import { UserMessageData } from './UserMessageData'; + +export class RoomUnitParser implements IMessageParser +{ + private _users: UserMessageData[]; + + public flush(): boolean + { + this._users = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._users = []; + + const totalUsers = wrapper.readInt(); + + let i = 0; + + while(i < totalUsers) + { + const id = wrapper.readInt(); + const username = wrapper.readString(); + const custom = wrapper.readString(); + let figure = wrapper.readString(); + const roomIndex = wrapper.readInt(); + const x = wrapper.readInt(); + const y = wrapper.readInt(); + const z = parseFloat(wrapper.readString()); + const direction = wrapper.readInt(); + const type = wrapper.readInt(); + + const user = new UserMessageData(roomIndex); + + user.dir = direction; + user.name = username; + user.custom = custom; + user.x = x; + user.y = y; + user.z = z; + + this._users.push(user); + + if(type === 1) + { + user.webID = id; + user.userType = RoomObjectType.USER; + user.sex = this.resolveSex(wrapper.readString()); + user.groupID = ('' + wrapper.readInt()); + user.groupStatus = wrapper.readInt(); + user.groupName = wrapper.readString(); + + const swimFigure = wrapper.readString(); + + if(swimFigure !== '') figure = this.convertSwimFigure(swimFigure, figure, user.sex); + + user.figure = figure; + user.activityPoints = wrapper.readInt(); + user.isModerator = wrapper.readBoolean(); + } + + else if(type === 2) + { + user.userType = RoomObjectType.PET; + user.figure = figure; + user.webID = id; + user.subType = wrapper.readInt().toString(); + user.ownerId = wrapper.readInt(); + user.ownerName = wrapper.readString(); + user.rarityLevel = wrapper.readInt(); + user.hasSaddle = wrapper.readBoolean(); + user.isRiding = wrapper.readBoolean(); + user.canBreed = wrapper.readBoolean(); + user.canHarvest = wrapper.readBoolean(); + user.canRevive = wrapper.readBoolean(); + user.hasBreedingPermission = wrapper.readBoolean(); + user.petLevel = wrapper.readInt(); + user.petPosture = wrapper.readString(); + } + + else if(type === 3) + { + user.userType = RoomObjectType.BOT; + user.webID = (roomIndex * -1); + + if(figure.indexOf('/') === -1) user.figure = figure; + else user.figure = 'hr-100-.hd-180-1.ch-876-66.lg-270-94.sh-300-64'; + + user.sex = UserMessageData.M; + } + + else if(type === 4) + { + user.userType = RoomObjectType.RENTABLE_BOT; + user.webID = id; + user.sex = this.resolveSex(wrapper.readString()); + user.figure = figure; + user.ownerId = wrapper.readInt(); + user.ownerName = wrapper.readString(); + + const totalSkills = wrapper.readInt(); + + if(totalSkills) + { + const skills: number[] = []; + + let j = 0; + + while(j < totalSkills) + { + skills.push(wrapper.readShort()); + + j++; + } + + user.botSkills = skills; + } + } + + i++; + } + + return true; + } + + private resolveSex(sex: string): string + { + if(sex.substr(0, 1).toLowerCase() === 'f') return UserMessageData.F; + + return UserMessageData.M; + } + + private convertSwimFigure(k: string, _arg_2: string, _arg_3: string): string + { + const _local_4 = _arg_2.split('.'); + let _local_5 = 1; + let _local_6 = 1; + let _local_7 = 1; + const _local_8 = 10000; + let i = 0; + + while(i < _local_4.length) + { + const _local_13 = _local_4[i]; + const _local_14 = _local_13.split('-'); + + if(_local_14.length > 2) + { + const _local_15 = _local_14[0]; + + if(_local_15 === 'hd') _local_5 = parseInt(_local_14[2]); + } + + i++; + } + + const _local_10 = ['238,238,238', '250,56,49', '253,146,160', '42,199,210', '53,51,44', '239,255,146', '198,255,152', '255,146,90', '157,89,126', '182,243,255', '109,255,51', '51,120,201', '255,182,49', '223,161,233', '249,251,50', '202,175,143', '197,198,197', '71,98,61', '138,131,97', '255,140,51', '84,198,39', '30,108,153', '152,79,136', '119,200,255', '255,192,142', '60,75,135', '124,44,71', '215,255,227', '143,63,28', '255,99,147', '31,155,121', '253,255,51']; + const _local_11 = k.split('='); + + if(_local_11.length > 1) + { + const _local_16 = _local_11[1].split('/'); + const _local_17 = _local_16[0]; + const _local_18 = _local_16[1]; + + if(_arg_3 === 'F') _local_7 = 10010; + else _local_7 = 10011; + + const _local_19 = _local_10.indexOf(_local_18); + + _local_6 = ((_local_8 + _local_19) + 1); + } + + return _arg_2 + ((((('.bds-10001-' + _local_5) + '.ss-') + _local_7) + '-') + _local_6); + } + + public get users(): UserMessageData[] + { + return this._users; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/room/unit/RoomUnitRemoveParser.ts b/src/nitro/communication/messages/parser/room/unit/RoomUnitRemoveParser.ts new file mode 100644 index 00000000..7977c2b4 --- /dev/null +++ b/src/nitro/communication/messages/parser/room/unit/RoomUnitRemoveParser.ts @@ -0,0 +1,28 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class RoomUnitRemoveParser implements IMessageParser +{ + private _unitId: number; + + public flush(): boolean + { + this._unitId = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._unitId = parseInt(wrapper.readString()); + + return true; + } + + public get unitId(): number + { + return this._unitId; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/room/unit/RoomUnitStatusAction.ts b/src/nitro/communication/messages/parser/room/unit/RoomUnitStatusAction.ts new file mode 100644 index 00000000..be47333b --- /dev/null +++ b/src/nitro/communication/messages/parser/room/unit/RoomUnitStatusAction.ts @@ -0,0 +1,21 @@ +export class RoomUnitStatusAction +{ + private _action: string; + private _value: string; + + constructor(action: string, value: string) + { + this._action = action; + this._value = value; + } + + public get action(): string + { + return this._action; + } + + public get value(): string + { + return this._value; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/room/unit/RoomUnitStatusMessage.ts b/src/nitro/communication/messages/parser/room/unit/RoomUnitStatusMessage.ts new file mode 100644 index 00000000..1238db85 --- /dev/null +++ b/src/nitro/communication/messages/parser/room/unit/RoomUnitStatusMessage.ts @@ -0,0 +1,100 @@ +import { RoomUnitStatusAction } from './RoomUnitStatusAction'; + +export class RoomUnitStatusMessage +{ + private _id: number; + private _x: number; + private _y: number; + private _z: number; + private _height: number; + private _headDirection: number; + private _direction: number; + private _targetX: number; + private _targetY: number; + private _targetZ: number; + private _didMove: boolean; + private _canStandUp: boolean; + private _actions: RoomUnitStatusAction[]; + + constructor(id: number, x: number, y: number, z: number, height: number, headDirection: number, direction: number, targetX: number = 0, targetY: number = 0, targetZ: number = 0, didMove: boolean, canStandUp: boolean, actions: RoomUnitStatusAction[]) + { + this._id = id; + this._x = x; + this._y = y; + this._z = z; + this._height = height; + this._headDirection = headDirection; + this._direction = direction; + this._targetX = targetX; + this._targetY = targetY; + this._targetZ = targetZ; + this._didMove = didMove; + this._canStandUp = canStandUp; + this._actions = actions || []; + } + + public get id(): number + { + return this._id; + } + + public get x(): number + { + return this._x; + } + + public get y(): number + { + return this._y; + } + + public get z(): number + { + return this._z; + } + + public get height(): number + { + return this._height; + } + + public get headDirection(): number + { + return this._headDirection; + } + + public get direction(): number + { + return this._direction; + } + + public get targetX(): number + { + return this._targetX; + } + + public get targetY(): number + { + return this._targetY; + } + + public get targetZ(): number + { + return this._targetZ; + } + + public get didMove(): boolean + { + return this._didMove; + } + + public get canStandUp(): boolean + { + return this._canStandUp; + } + + public get actions(): RoomUnitStatusAction[] + { + return this._actions; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/room/unit/RoomUnitStatusParser.ts b/src/nitro/communication/messages/parser/room/unit/RoomUnitStatusParser.ts new file mode 100644 index 00000000..83f76770 --- /dev/null +++ b/src/nitro/communication/messages/parser/room/unit/RoomUnitStatusParser.ts @@ -0,0 +1,120 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; +import { RoomUnitStatusAction } from './RoomUnitStatusAction'; +import { RoomUnitStatusMessage } from './RoomUnitStatusMessage'; + +export class RoomUnitStatusParser implements IMessageParser +{ + private _statuses: RoomUnitStatusMessage[]; + + public flush(): boolean + { + this._statuses = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + let totalUnits = wrapper.readInt(); + + while(totalUnits > 0) + { + const status = this.parseStatus(wrapper); + + if(!status) + { + totalUnits--; + + continue; + } + + this._statuses.push(status); + + totalUnits--; + } + + return true; + } + + public parseStatus(wrapper: IMessageDataWrapper): RoomUnitStatusMessage + { + if(!wrapper) return null; + + const unitId = wrapper.readInt(); + const x = wrapper.readInt(); + const y = wrapper.readInt(); + const z = parseFloat(wrapper.readString()); + const headDirection = ((wrapper.readInt() % 8) * 45); + const direction = ((wrapper.readInt() % 8) * 45); + const actions = wrapper.readString(); + + let targetX = 0; + let targetY = 0; + let targetZ = 0; + let height = 0; + let canStandUp = false; + let didMove = false; + const isSlide = false; + + if(actions) + { + const actionParts = actions.split('/'); + + const totalActions = actionParts.length; + + const statusActions: RoomUnitStatusAction[] = []; + + if(totalActions) + { + for(let i = 0; i < totalActions; i++) + { + const action = actionParts[i]; + + if(!action) continue; + + const [ key, value, extra ] = action.split(' '); + + if(!key || !value) continue; + + switch(key) + { + case 'mv': + [ targetX, targetY, targetZ ] = value.split(',').map(a => parseFloat(a)); + + didMove = true; + + break; + case 'sit': { + const sitHeight = parseFloat(value); + + if(extra !== undefined) canStandUp = value === '1'; + + height = sitHeight; + + break; + } + case 'lay': { + const layHeight = parseFloat(value); + + height = layHeight; + + break; + } + } + + statusActions.push(new RoomUnitStatusAction(key, value)); + } + } + + this._statuses.push(new RoomUnitStatusMessage(unitId, x, y, z, height, headDirection, direction, targetX, targetY, targetZ, didMove, canStandUp, statusActions)); + } + } + + public get statuses(): RoomUnitStatusMessage[] + { + return this._statuses; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/room/unit/UserMessageData.ts b/src/nitro/communication/messages/parser/room/unit/UserMessageData.ts new file mode 100644 index 00000000..50052c72 --- /dev/null +++ b/src/nitro/communication/messages/parser/room/unit/UserMessageData.ts @@ -0,0 +1,412 @@ +export class UserMessageData +{ + public static M: string = 'M'; + public static F: string = 'F'; + + private _roomIndex: number = 0; + private _x: number = 0; + private _y: number = 0; + private _z: number = 0; + private _dir: number = 0; + private _name: string = ''; + private _userType: number = 0; + private _sex: string = ''; + private _figure: string = ''; + private _custom: string = ''; + private _activityPoints: number = 0; + private _webID: number = 0; + private _groupID: string = ''; + private _groupStatus: number = 0; + private _groupName: string = ''; + private _subType: string = ''; + private _ownerId: number = 0; + private _ownerName: string = ''; + private _rarityLevel: number = 0; + private _hasSaddle: boolean = false; + private _isRiding: boolean = false; + private _canBreed: boolean = false; + private _canHarvest: boolean = false; + private _canRevive: boolean = false; + private _hasBreedingPermission: boolean = false; + private _petLevel: number = 0; + private _petPosture: string = ''; + private _botSkills: number[] = []; + private _isModerator: boolean = false; + private _isReadOnly: boolean = false; + + constructor(k: number) + { + this._roomIndex = k; + } + + public _Str_4710(): void + { + this._isReadOnly = true; + } + + public get roomIndex(): number + { + return this._roomIndex; + } + + public get x(): number + { + return this._x; + } + + public set x(k: number) + { + if(!this._isReadOnly) + { + this._x = k; + } + } + + public get y(): number + { + return this._y; + } + + public set y(k: number) + { + if(!this._isReadOnly) + { + this._y = k; + } + } + + public get z(): number + { + return this._z; + } + + public set z(k: number) + { + if(!this._isReadOnly) + { + this._z = k; + } + } + + public get dir(): number + { + return this._dir; + } + + public set dir(k: number) + { + if(!this._isReadOnly) + { + this._dir = k; + } + } + + public get name(): string + { + return this._name; + } + + public set name(k: string) + { + if(!this._isReadOnly) + { + this._name = k; + } + } + + public get userType(): number + { + return this._userType; + } + + public set userType(k: number) + { + if(!this._isReadOnly) + { + this._userType = k; + } + } + + public get sex(): string + { + return this._sex; + } + + public set sex(k: string) + { + if(!this._isReadOnly) + { + this._sex = k; + } + } + + public get figure(): string + { + return this._figure; + } + + public set figure(k: string) + { + if(!this._isReadOnly) + { + this._figure = k; + } + } + + public get custom(): string + { + return this._custom; + } + + public set custom(k: string) + { + if(!this._isReadOnly) + { + this._custom = k; + } + } + + public get activityPoints(): number + { + return this._activityPoints; + } + + public set activityPoints(k: number) + { + if(!this._isReadOnly) + { + this._activityPoints = k; + } + } + + public get webID(): number + { + return this._webID; + } + + public set webID(k: number) + { + if(!this._isReadOnly) + { + this._webID = k; + } + } + + public get groupID(): string + { + return this._groupID; + } + + public set groupID(k: string) + { + if(!this._isReadOnly) + { + this._groupID = k; + } + } + + public get groupName(): string + { + return this._groupName; + } + + public set groupName(k: string) + { + if(!this._isReadOnly) + { + this._groupName = k; + } + } + + public get groupStatus(): number + { + return this._groupStatus; + } + + public set groupStatus(k: number) + { + if(!this._isReadOnly) + { + this._groupStatus = k; + } + } + + public get subType(): string + { + return this._subType; + } + + public set subType(k: string) + { + if(!this._isReadOnly) + { + this._subType = k; + } + } + + public get ownerId(): number + { + return this._ownerId; + } + + public set ownerId(k: number) + { + if(!this._isReadOnly) + { + this._ownerId = k; + } + } + + public get ownerName(): string + { + return this._ownerName; + } + + public set ownerName(k: string) + { + if(!this._isReadOnly) + { + this._ownerName = k; + } + } + + public get rarityLevel(): number + { + return this._rarityLevel; + } + + public set rarityLevel(k: number) + { + if(!this._isReadOnly) + { + this._rarityLevel = k; + } + } + + public get hasSaddle(): boolean + { + return this._hasSaddle; + } + + public set hasSaddle(k: boolean) + { + if(!this._isReadOnly) + { + this._hasSaddle = k; + } + } + + public get isRiding(): boolean + { + return this._isRiding; + } + + public set isRiding(k: boolean) + { + if(!this._isReadOnly) + { + this._isRiding = k; + } + } + + public get canBreed(): boolean + { + return this._canBreed; + } + + public set canBreed(k: boolean) + { + if(!this._isReadOnly) + { + this._canBreed = k; + } + } + + public get canHarvest(): boolean + { + return this._canHarvest; + } + + public set canHarvest(k: boolean) + { + if(!this._isReadOnly) + { + this._canHarvest = k; + } + } + + public get canRevive(): boolean + { + return this._canRevive; + } + + public set canRevive(k: boolean) + { + if(!this._isReadOnly) + { + this._canRevive = k; + } + } + + public get hasBreedingPermission(): boolean + { + return this._hasBreedingPermission; + } + + public set hasBreedingPermission(k: boolean) + { + if(!this._isReadOnly) + { + this._hasBreedingPermission = k; + } + } + + public get petLevel(): number + { + return this._petLevel; + } + + public set petLevel(k: number) + { + if(!this._isReadOnly) + { + this._petLevel = k; + } + } + + public get petPosture(): string + { + return this._petPosture; + } + + public set petPosture(k: string) + { + if(!this._isReadOnly) + { + this._petPosture = k; + } + } + + public get botSkills(): number[] + { + return this._botSkills; + } + + public set botSkills(k: number[]) + { + this._botSkills = k; + } + + public get isModerator(): boolean + { + return this._isModerator; + } + + public set isModerator(k: boolean) + { + if(!this._isReadOnly) + { + this._isModerator = k; + } + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/room/unit/chat/FloodControlParser.ts b/src/nitro/communication/messages/parser/room/unit/chat/FloodControlParser.ts new file mode 100644 index 00000000..af4c572d --- /dev/null +++ b/src/nitro/communication/messages/parser/room/unit/chat/FloodControlParser.ts @@ -0,0 +1,28 @@ +import { IMessageDataWrapper } from '../../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../../core/communication/messages/IMessageParser'; + +export class FloodControlParser implements IMessageParser +{ + private _seconds: number; + + public flush(): boolean + { + this._seconds = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._seconds = wrapper.readInt(); + + return true; + } + + public get seconds(): number + { + return this._seconds; + } +} diff --git a/src/nitro/communication/messages/parser/room/unit/chat/RemainingMuteParser.ts b/src/nitro/communication/messages/parser/room/unit/chat/RemainingMuteParser.ts new file mode 100644 index 00000000..0e937ef8 --- /dev/null +++ b/src/nitro/communication/messages/parser/room/unit/chat/RemainingMuteParser.ts @@ -0,0 +1,28 @@ +import { IMessageDataWrapper } from '../../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../../core/communication/messages/IMessageParser'; + +export class RemainingMuteParser implements IMessageParser +{ + private _seconds: number; + + public flush(): boolean + { + this._seconds = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._seconds = wrapper.readInt(); + + return true; + } + + public get seconds(): number + { + return this._seconds; + } +} diff --git a/src/nitro/communication/messages/parser/room/unit/chat/RoomUnitChatParser.ts b/src/nitro/communication/messages/parser/room/unit/chat/RoomUnitChatParser.ts new file mode 100644 index 00000000..4d9a1729 --- /dev/null +++ b/src/nitro/communication/messages/parser/room/unit/chat/RoomUnitChatParser.ts @@ -0,0 +1,88 @@ +import { IMessageDataWrapper } from '../../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../../core/communication/messages/IMessageParser'; + +export class RoomUnitChatParser implements IMessageParser +{ + private _roomIndex: number; + private _message: string; + private _gesture: number; + private _bubble: number; + private _urls: string[]; + private _messageLength: number; + + public flush(): boolean + { + this._roomIndex = null; + this._message = null; + this._gesture = 0; + this._bubble = 0; + this._urls = []; + this._messageLength = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._roomIndex = wrapper.readInt(); + this._message = wrapper.readString(); + this._gesture = wrapper.readInt(); + this._bubble = wrapper.readInt(); + + this.parseUrls(wrapper); + + this._messageLength = wrapper.readInt(); + + return true; + } + + private parseUrls(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._urls = []; + + let totalUrls = wrapper.readInt(); + + while(totalUrls > 0) + { + this._urls.push(wrapper.readString()); + + totalUrls--; + } + + return true; + } + + public get roomIndex(): number + { + return this._roomIndex; + } + + public get message(): string + { + return this._message; + } + + public get gesture(): number + { + return this._gesture; + } + + public get bubble(): number + { + return this._bubble; + } + + public get urls(): string[] + { + return this._urls; + } + + public get messageLength(): number + { + return this._messageLength; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/room/unit/chat/RoomUnitTypingParser.ts b/src/nitro/communication/messages/parser/room/unit/chat/RoomUnitTypingParser.ts new file mode 100644 index 00000000..2e9c5a94 --- /dev/null +++ b/src/nitro/communication/messages/parser/room/unit/chat/RoomUnitTypingParser.ts @@ -0,0 +1,36 @@ +import { IMessageDataWrapper } from '../../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../../core/communication/messages/IMessageParser'; + +export class RoomUnitTypingParser implements IMessageParser +{ + private _unitId: number; + private _isTyping: boolean; + + public flush(): boolean + { + this._unitId = null; + this._isTyping = false; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._unitId = wrapper.readInt(); + this._isTyping = wrapper.readInt() === 1 ? true : false; + + return true; + } + + public get unitId(): number + { + return this._unitId; + } + + public get isTyping(): boolean + { + return this._isTyping; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/roomevents/RoomMutedParser.ts b/src/nitro/communication/messages/parser/roomevents/RoomMutedParser.ts new file mode 100644 index 00000000..e913b659 --- /dev/null +++ b/src/nitro/communication/messages/parser/roomevents/RoomMutedParser.ts @@ -0,0 +1,26 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; + +export class RoomMutedParser implements IMessageParser +{ + private _isMuted:boolean; + + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._isMuted = wrapper.readBoolean(); + + return true; + } + + public get isMuted(): boolean + { + return this._isMuted; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/roomevents/WiredFurniActionParser.ts b/src/nitro/communication/messages/parser/roomevents/WiredFurniActionParser.ts new file mode 100644 index 00000000..f31ae4e0 --- /dev/null +++ b/src/nitro/communication/messages/parser/roomevents/WiredFurniActionParser.ts @@ -0,0 +1,29 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; +import { ActionDefinition } from '../../incoming/roomevents/ActionDefinition'; + +export class WiredFurniActionParser implements IMessageParser +{ + private _definition: ActionDefinition; + + public flush(): boolean + { + this._definition = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._definition = new ActionDefinition(wrapper); + + return true; + } + + public get definition(): ActionDefinition + { + return this._definition; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/roomevents/WiredFurniConditionParser.ts b/src/nitro/communication/messages/parser/roomevents/WiredFurniConditionParser.ts new file mode 100644 index 00000000..9cc32562 --- /dev/null +++ b/src/nitro/communication/messages/parser/roomevents/WiredFurniConditionParser.ts @@ -0,0 +1,29 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; +import { ConditionDefinition } from '../../incoming/roomevents/ConditionDefinition'; + +export class WiredFurniConditionParser implements IMessageParser +{ + private _definition: ConditionDefinition; + + public flush(): boolean + { + this._definition = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._definition = new ConditionDefinition(wrapper); + + return true; + } + + public get definition(): ConditionDefinition + { + return this._definition; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/roomevents/WiredFurniTriggerParser.ts b/src/nitro/communication/messages/parser/roomevents/WiredFurniTriggerParser.ts new file mode 100644 index 00000000..6e36a66b --- /dev/null +++ b/src/nitro/communication/messages/parser/roomevents/WiredFurniTriggerParser.ts @@ -0,0 +1,29 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; +import { TriggerDefinition } from '../../incoming/roomevents/TriggerDefinition'; + +export class WiredFurniTriggerParser implements IMessageParser +{ + private _definition: TriggerDefinition; + + public flush(): boolean + { + this._definition = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._definition = new TriggerDefinition(wrapper); + + return true; + } + + public get definition(): TriggerDefinition + { + return this._definition; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/roomevents/WiredOpenParser.ts b/src/nitro/communication/messages/parser/roomevents/WiredOpenParser.ts new file mode 100644 index 00000000..1824a001 --- /dev/null +++ b/src/nitro/communication/messages/parser/roomevents/WiredOpenParser.ts @@ -0,0 +1,28 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; + +export class WiredOpenParser implements IMessageParser +{ + private _stuffId: number; + + public flush(): boolean + { + this._stuffId = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._stuffId = wrapper.readInt(); + + return true; + } + + public get stuffId(): number + { + return this._stuffId; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/roomevents/WiredRewardResultMessageParser.ts b/src/nitro/communication/messages/parser/roomevents/WiredRewardResultMessageParser.ts new file mode 100644 index 00000000..a9606920 --- /dev/null +++ b/src/nitro/communication/messages/parser/roomevents/WiredRewardResultMessageParser.ts @@ -0,0 +1,28 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; + +export class WiredRewardResultMessageParser implements IMessageParser +{ + private _reason: number; + + public flush(): boolean + { + this._reason = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._reason = wrapper.readInt(); + + return true; + } + + public get reason(): number + { + return this._reason; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/roomevents/WiredSaveSuccessParser.ts b/src/nitro/communication/messages/parser/roomevents/WiredSaveSuccessParser.ts new file mode 100644 index 00000000..5e8d0513 --- /dev/null +++ b/src/nitro/communication/messages/parser/roomevents/WiredSaveSuccessParser.ts @@ -0,0 +1,17 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; + +export class WiredSaveSuccessParser implements IMessageParser +{ + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + return true; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/roomevents/WiredValidationErrorParser.ts b/src/nitro/communication/messages/parser/roomevents/WiredValidationErrorParser.ts new file mode 100644 index 00000000..0725c70e --- /dev/null +++ b/src/nitro/communication/messages/parser/roomevents/WiredValidationErrorParser.ts @@ -0,0 +1,28 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; + +export class WiredValidationErrorParser implements IMessageParser +{ + private _info: string; + + public flush(): boolean + { + this._info = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._info = wrapper.readString(); + + return true; + } + + public get info(): string + { + return this._info; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/security/AuthenticatedParser.ts b/src/nitro/communication/messages/parser/security/AuthenticatedParser.ts new file mode 100644 index 00000000..cf874899 --- /dev/null +++ b/src/nitro/communication/messages/parser/security/AuthenticatedParser.ts @@ -0,0 +1,17 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; + +export class AuthenticatedParser implements IMessageParser +{ + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + return true; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/user/IgnoreResultParser.ts b/src/nitro/communication/messages/parser/user/IgnoreResultParser.ts new file mode 100644 index 00000000..4ce91f38 --- /dev/null +++ b/src/nitro/communication/messages/parser/user/IgnoreResultParser.ts @@ -0,0 +1,36 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; + +export class IgnoreResultParser implements IMessageParser +{ + private _result: number; + private _name: string; + + public flush(): boolean + { + this._result = -1; + this._name = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._result = wrapper.readInt(); + this._name = wrapper.readString(); + + return true; + } + + public get result(): number + { + return this._result; + } + + public get name(): string + { + return this._name; + } +} diff --git a/src/nitro/communication/messages/parser/user/IgnoredUsersParser.ts b/src/nitro/communication/messages/parser/user/IgnoredUsersParser.ts new file mode 100644 index 00000000..ea412240 --- /dev/null +++ b/src/nitro/communication/messages/parser/user/IgnoredUsersParser.ts @@ -0,0 +1,37 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; + +export class IgnoredUsersParser implements IMessageParser +{ + private _ignoredUsers: string[]; + + public flush(): boolean + { + this._ignoredUsers = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._ignoredUsers = []; + + let count = wrapper.readInt(); + + while(count > 0) + { + this._ignoredUsers.push(wrapper.readString()); + + count--; + } + + return true; + } + + public get ignoredUsers(): string[] + { + return this._ignoredUsers; + } +} diff --git a/src/nitro/communication/messages/parser/user/InClientLinkParser.ts b/src/nitro/communication/messages/parser/user/InClientLinkParser.ts new file mode 100644 index 00000000..970e3cd1 --- /dev/null +++ b/src/nitro/communication/messages/parser/user/InClientLinkParser.ts @@ -0,0 +1,26 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../core/communication/messages/IMessageParser'; + +export class InClientLinkParser implements IMessageParser +{ + private _link: string; + + public flush(): boolean + { + this._link = null; + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._link = wrapper.readString(); + return true; + } + + public get link(): string + { + return this._link; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/user/access/UserPerksParser.ts b/src/nitro/communication/messages/parser/user/access/UserPerksParser.ts new file mode 100644 index 00000000..8884852f --- /dev/null +++ b/src/nitro/communication/messages/parser/user/access/UserPerksParser.ts @@ -0,0 +1,17 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class UserPerksParser implements IMessageParser +{ + public flush(): boolean + { + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + return true; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/user/access/UserPermissionsParser.ts b/src/nitro/communication/messages/parser/user/access/UserPermissionsParser.ts new file mode 100644 index 00000000..60e7d66a --- /dev/null +++ b/src/nitro/communication/messages/parser/user/access/UserPermissionsParser.ts @@ -0,0 +1,44 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class UserPermissionsParser implements IMessageParser +{ + private _clubLevel: number; + private _securityLevel: number; + private _isAmbassador: boolean; + + public flush(): boolean + { + this._clubLevel = 0; + this._securityLevel = 0; + this._isAmbassador = false; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._clubLevel = wrapper.readInt(); + this._securityLevel = wrapper.readInt(); + this._isAmbassador = wrapper.readBoolean(); + + return true; + } + + public get clubLevel(): number + { + return this._clubLevel; + } + + public get securityLevel(): number + { + return this._securityLevel; + } + + public get isAmbassador(): boolean + { + return this._isAmbassador; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/user/data/UserCurrentBadgesParser.ts b/src/nitro/communication/messages/parser/user/data/UserCurrentBadgesParser.ts new file mode 100644 index 00000000..eb791649 --- /dev/null +++ b/src/nitro/communication/messages/parser/user/data/UserCurrentBadgesParser.ts @@ -0,0 +1,47 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class UserCurrentBadgesParser implements IMessageParser +{ + private _userId: number; + private _badges: string[]; + + public flush(): boolean + { + this._userId = null; + this._badges = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._userId = wrapper.readInt(); + + let totalBadges = wrapper.readInt(); + + while(totalBadges > 0) + { + const slotId = wrapper.readInt(); + const badgeCode = wrapper.readString(); + + this._badges.push(badgeCode); + + totalBadges--; + } + + return true; + } + + public get userId(): number + { + return this._userId; + } + + public get badges(): string[] + { + return this._badges; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/user/data/UserFigureParser.ts b/src/nitro/communication/messages/parser/user/data/UserFigureParser.ts new file mode 100644 index 00000000..d9e4ade8 --- /dev/null +++ b/src/nitro/communication/messages/parser/user/data/UserFigureParser.ts @@ -0,0 +1,36 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class UserFigureParser implements IMessageParser +{ + private _figure: string; + private _gender: string; + + public flush(): boolean + { + this._figure = null; + this._gender = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._figure = wrapper.readString(); + this._gender = wrapper.readString(); + + return true; + } + + public get figure(): string + { + return this._figure; + } + + public get gender(): string + { + return this._gender; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/user/data/UserInfoDataParser.ts b/src/nitro/communication/messages/parser/user/data/UserInfoDataParser.ts new file mode 100644 index 00000000..10905826 --- /dev/null +++ b/src/nitro/communication/messages/parser/user/data/UserInfoDataParser.ts @@ -0,0 +1,139 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; + +export class UserInfoDataParser +{ + private _userId: number; + private _username: string; + private _figure: string; + private _gender: string; + private _motto: string; + private _realName: string; + private _directMail: boolean; + private _respectsReceived: number; + private _respectsRemaining: number; + private _respectsPetRemaining: number; + private _streamPublishingAllowed: boolean; + private _lastAccessDate: string; + private _canChangeName: boolean; + private _safetyLocked: boolean; + + constructor(wrapper: IMessageDataWrapper) + { + if(!wrapper) throw new Error('invalid_wrapper'); + + this.flush(); + this.parse(wrapper); + } + + public flush(): boolean + { + this._userId = 0; + this._username = null; + this._figure = null; + this._gender = null; + this._motto = null; + this._realName = null; + this._directMail = false; + this._respectsReceived = 0; + this._respectsRemaining = 0; + this._respectsPetRemaining = 0; + this._streamPublishingAllowed = false; + this._lastAccessDate = null; + this._canChangeName = false; + this._safetyLocked = false; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._userId = wrapper.readInt(); + this._username = wrapper.readString(); + this._figure = wrapper.readString(); + this._gender = wrapper.readString(); + this._motto = wrapper.readString(); + this._realName = wrapper.readString(); + this._directMail = wrapper.readBoolean(); + this._respectsReceived = wrapper.readInt(); + this._respectsRemaining = wrapper.readInt(); + this._respectsPetRemaining = wrapper.readInt(); + this._streamPublishingAllowed = wrapper.readBoolean(); + this._lastAccessDate = wrapper.readString(); + this._canChangeName = wrapper.readBoolean(); + this._safetyLocked = wrapper.readBoolean(); + + return true; + } + + public get userId(): number + { + return this._userId; + } + + public get username(): string + { + return this._username; + } + + public get figure(): string + { + return this._figure; + } + + public get gender(): string + { + return this._gender; + } + + public get motto(): string + { + return this._motto; + } + + public get realName(): string + { + return this._realName; + } + + public get directMail(): boolean + { + return this._directMail; + } + + public get respectsReceived(): number + { + return this._respectsReceived; + } + + public get respectsRemaining(): number + { + return this._respectsRemaining; + } + + public get respectsPetRemaining(): number + { + return this._respectsPetRemaining; + } + + public get streamPublishingAllowed(): boolean + { + return this._streamPublishingAllowed; + } + + public get lastAccessedDate(): string + { + return this._lastAccessDate; + } + + public get canChangeName(): boolean + { + return this._canChangeName; + } + + public get safetyLocked(): boolean + { + return this._safetyLocked; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/user/data/UserInfoParser.ts b/src/nitro/communication/messages/parser/user/data/UserInfoParser.ts new file mode 100644 index 00000000..24b94735 --- /dev/null +++ b/src/nitro/communication/messages/parser/user/data/UserInfoParser.ts @@ -0,0 +1,31 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; +import { UserInfoDataParser } from './UserInfoDataParser'; + +export class UserInfoParser implements IMessageParser +{ + private _userInfo: UserInfoDataParser; + + public flush(): boolean + { + this._userInfo = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._userInfo = new UserInfoDataParser(wrapper); + + if(!this._userInfo) return false; + + return true; + } + + public get userInfo(): UserInfoDataParser + { + return this._userInfo; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/user/data/UserNameChangeMessageParser.ts b/src/nitro/communication/messages/parser/user/data/UserNameChangeMessageParser.ts new file mode 100644 index 00000000..0992fae7 --- /dev/null +++ b/src/nitro/communication/messages/parser/user/data/UserNameChangeMessageParser.ts @@ -0,0 +1,44 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class UserNameChangeMessageParser implements IMessageParser +{ + private _webId: number; + private _id: number; + private _newName: string; + + public flush(): boolean + { + this._webId = -1; + this._id = -1; + this._newName = ''; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._webId = wrapper.readInt(); + this._id = wrapper.readInt(); + this._newName = wrapper.readString(); + + return true; + } + + public get webId(): number + { + return this._webId; + } + + public get id(): number + { + return this._id; + } + + public get newName(): string + { + return this._newName; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/user/data/UserProfileParser.ts b/src/nitro/communication/messages/parser/user/data/UserProfileParser.ts new file mode 100644 index 00000000..344e4a7b --- /dev/null +++ b/src/nitro/communication/messages/parser/user/data/UserProfileParser.ts @@ -0,0 +1,125 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; +import { GroupDataParser } from '../../group/utils/GroupDataParser'; + +export class UserProfileParser implements IMessageParser +{ + private _id: number; + private _username: string; + private _figure: string; + private _motto: string; + private _registration: string; + private _achievementPoints: number; + private _friendsCount: number; + private _isMyFriend: boolean; + private _requestSent: boolean; + private _isOnline: boolean; + private _groups: GroupDataParser[]; + private _lastVisit: number; + + public flush(): boolean + { + this._id = 0; + this._username = null; + this._figure = null; + this._motto = null; + this._registration = null; + this._achievementPoints = 0; + this._friendsCount = 0; + this._isMyFriend = false; + this._requestSent = false; + this._isOnline = false; + this._groups = []; + this._lastVisit = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._id = wrapper.readInt(); + this._username = wrapper.readString(); + this._figure = wrapper.readString(); + this._motto = wrapper.readString(); + this._registration = wrapper.readString(); + this._achievementPoints = wrapper.readInt(); + this._friendsCount = wrapper.readInt(); + this._isMyFriend = wrapper.readBoolean(); + this._requestSent = wrapper.readBoolean(); + this._isOnline = wrapper.readBoolean(); + let groupsCount = wrapper.readInt(); + + while(groupsCount > 0) + { + this._groups.push(new GroupDataParser(wrapper)); + + groupsCount--; + } + + this._lastVisit = wrapper.readInt(); + + return true; + } + + public get id(): number + { + return this._id; + } + + public get username(): string + { + return this._username; + } + + public get figure(): string + { + return this._figure; + } + + public get motto(): string + { + return this._motto; + } + + public get registration(): string + { + return this._registration; + } + + public get achievementPoints(): number + { + return this._achievementPoints; + } + + public get friendsCount(): number + { + return this._friendsCount; + } + + public get isMyFriend(): boolean + { + return this._isMyFriend; + } + + public get requestSent(): boolean + { + return this._requestSent; + } + + public get isOnline(): boolean + { + return this._isOnline; + } + + public get groups(): GroupDataParser[] + { + return this._groups; + } + + public get lastVisit(): number + { + return this._lastVisit; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/user/data/UserRelationshipDataParser.ts b/src/nitro/communication/messages/parser/user/data/UserRelationshipDataParser.ts new file mode 100644 index 00000000..29d842b9 --- /dev/null +++ b/src/nitro/communication/messages/parser/user/data/UserRelationshipDataParser.ts @@ -0,0 +1,61 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { RelationshipStatusEnum } from '../../../../../enums/RelationshipStatusEnum'; + +export class UserRelationshipDataParser +{ + private _level: RelationshipStatusEnum; + private _userId: number; + private _username: string; + private _figure: string; + + constructor(wrapper: IMessageDataWrapper) + { + if(!wrapper) throw new Error('invalid_wrapper'); + + this.flush(); + this.parse(wrapper); + } + + public flush(): boolean + { + this._level = RelationshipStatusEnum.NONE; + this._userId = 0; + this._username = null; + this._figure = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._level = wrapper.readInt(); + wrapper.readInt(); + this._userId = wrapper.readInt(); + this._username = wrapper.readString(); + this._figure = wrapper.readString(); + + return true; + } + + public get level(): RelationshipStatusEnum + { + return this._level; + } + + public get userId(): number + { + return this._userId; + } + + public get username(): string + { + return this._username; + } + + public get figure(): string + { + return this._figure; + } +} diff --git a/src/nitro/communication/messages/parser/user/data/UserRelationshipsParser.ts b/src/nitro/communication/messages/parser/user/data/UserRelationshipsParser.ts new file mode 100644 index 00000000..60ce1a84 --- /dev/null +++ b/src/nitro/communication/messages/parser/user/data/UserRelationshipsParser.ts @@ -0,0 +1,72 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; +import { RelationshipStatusEnum } from '../../../../../enums/RelationshipStatusEnum'; +import { UserRelationshipDataParser } from './UserRelationshipDataParser'; + +export class UserRelationshipsParser implements IMessageParser +{ + private _id: number; + private _hearts: UserRelationshipDataParser[]; + private _smiles: UserRelationshipDataParser[]; + private _bobbas: UserRelationshipDataParser[]; + + public flush(): boolean + { + this._id = 0; + this._hearts = []; + this._smiles = []; + this._bobbas = []; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._id = wrapper.readInt(); + let relationshipsCount = wrapper.readInt(); + + while(relationshipsCount > 0) + { + const relationship = new UserRelationshipDataParser(wrapper); + + if(relationship.level === RelationshipStatusEnum.HEART) + { + this._hearts.push(relationship); + } + else if(relationship.level === RelationshipStatusEnum.SMILE) + { + this._smiles.push(relationship); + } + else if(relationship.level === RelationshipStatusEnum.BOBBA) + { + this._bobbas.push(relationship); + } + + relationshipsCount--; + } + + return true; + } + + public get id(): number + { + return this._id; + } + + public get hearts(): UserRelationshipDataParser[] + { + return this._hearts; + } + + public get smiles(): UserRelationshipDataParser[] + { + return this._smiles; + } + + public get bobbas(): UserRelationshipDataParser[] + { + return this._bobbas; + } +} diff --git a/src/nitro/communication/messages/parser/user/data/UserSettingsParser.ts b/src/nitro/communication/messages/parser/user/data/UserSettingsParser.ts new file mode 100644 index 00000000..d71ffcaf --- /dev/null +++ b/src/nitro/communication/messages/parser/user/data/UserSettingsParser.ts @@ -0,0 +1,84 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class UserSettingsParser implements IMessageParser +{ + private _volumeSystem: number; + private _volumeFurni: number; + private _volumeTrax: number; + private _oldChat: boolean; + private _roomInvites: boolean; + private _cameraFollow: boolean; + private _flags: number; + private _chatType: number; + + public flush(): boolean + { + this._volumeSystem = 0; + this._volumeFurni = 0; + this._volumeTrax = 0; + this._oldChat = false; + this._roomInvites = false; + this._cameraFollow = false; + this._flags = 0; + this._chatType = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._volumeSystem = wrapper.readInt(); + this._volumeFurni = wrapper.readInt(); + this._volumeTrax = wrapper.readInt(); + this._oldChat = wrapper.readBoolean(); + this._roomInvites = wrapper.readBoolean(); + this._cameraFollow = wrapper.readBoolean(); + this._flags = wrapper.readInt(); + this._chatType = wrapper.readInt(); + + return true; + } + + public get volumeSystem(): number + { + return this._volumeSystem; + } + + public get volumeFurni(): number + { + return this._volumeFurni; + } + + public get volumeTrax(): number + { + return this._volumeTrax; + } + + public get oldChat(): boolean + { + return this._oldChat; + } + + public get roomInvites(): boolean + { + return this._roomInvites; + } + + public get cameraFollow(): boolean + { + return this._cameraFollow; + } + + public get flags(): number + { + return this._flags; + } + + public get chatType(): number + { + return this._chatType; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/user/inventory/currency/UserCreditsParser.ts b/src/nitro/communication/messages/parser/user/inventory/currency/UserCreditsParser.ts new file mode 100644 index 00000000..13dcf9c8 --- /dev/null +++ b/src/nitro/communication/messages/parser/user/inventory/currency/UserCreditsParser.ts @@ -0,0 +1,28 @@ +import { IMessageDataWrapper } from '../../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../../core/communication/messages/IMessageParser'; + +export class UserCreditsParser implements IMessageParser +{ + private _credits: string; + + public flush(): boolean + { + this._credits = null; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._credits = wrapper.readString(); + + return true; + } + + public get credits(): string + { + return this._credits; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/user/inventory/currency/UserCurrencyParser.ts b/src/nitro/communication/messages/parser/user/inventory/currency/UserCurrencyParser.ts new file mode 100644 index 00000000..6d017d92 --- /dev/null +++ b/src/nitro/communication/messages/parser/user/inventory/currency/UserCurrencyParser.ts @@ -0,0 +1,35 @@ +import { IMessageDataWrapper } from '../../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../../core/communication/messages/IMessageParser'; + +export class UserCurrencyParser implements IMessageParser +{ + private _currencies: Map; + + public flush(): boolean + { + this._currencies = new Map(); + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + let totalCurrencies = wrapper.readInt(); + + while(totalCurrencies > 0) + { + this._currencies.set(wrapper.readInt(), wrapper.readInt()); + + totalCurrencies--; + } + + return true; + } + + public get currencies(): Map + { + return this._currencies; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/user/inventory/currency/UserCurrencyUpdateParser.ts b/src/nitro/communication/messages/parser/user/inventory/currency/UserCurrencyUpdateParser.ts new file mode 100644 index 00000000..f6e2c3cd --- /dev/null +++ b/src/nitro/communication/messages/parser/user/inventory/currency/UserCurrencyUpdateParser.ts @@ -0,0 +1,44 @@ +import { IMessageDataWrapper } from '../../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../../core/communication/messages/IMessageParser'; + +export class UserCurrencyUpdateParser implements IMessageParser +{ + private _amount: number; + private _amountChanged: number; + private _type: number; + + public flush(): boolean + { + this._amount = 0; + this._amountChanged = 0; + this._type = -1; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._amount = wrapper.readInt(); + this._amountChanged = wrapper.readInt(); + this._type = wrapper.readInt(); + + return true; + } + + public get amount(): number + { + return this._amount; + } + + public get amountChanged(): number + { + return this._amountChanged; + } + + public get type(): number + { + return this._type; + } +} \ No newline at end of file diff --git a/src/nitro/communication/messages/parser/user/inventory/subscription/UserSubscriptionParser.ts b/src/nitro/communication/messages/parser/user/inventory/subscription/UserSubscriptionParser.ts new file mode 100644 index 00000000..9d9cdcf2 --- /dev/null +++ b/src/nitro/communication/messages/parser/user/inventory/subscription/UserSubscriptionParser.ts @@ -0,0 +1,102 @@ +import { IMessageDataWrapper } from '../../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../../core/communication/messages/IMessageParser'; + +export class UserSubscriptionParser implements IMessageParser +{ + public static _Str_14729: number = 3; + + private _name: string; + private _days: number; + private _int1: number; + private _months: number; + private _years: number; + private _hasEverBeenMember: boolean; + private _isVip: boolean; + private _pastClubDays: number; + private _pastVIPDays: number; + private _totalSeconds: number; + + public flush(): boolean + { + this._name = null; + this._days = 0; + this._int1 = 0; + this._months = 0; + this._years = 0; + this._hasEverBeenMember = false; + this._isVip = false; + this._pastClubDays = 0; + this._pastVIPDays = 0; + this._totalSeconds = 0; + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + this._name = wrapper.readString(); + this._days = wrapper.readInt(); + this._int1 = wrapper.readInt(); + this._months = wrapper.readInt(); + this._years = wrapper.readInt(); + this._hasEverBeenMember = wrapper.readBoolean(); + this._isVip = wrapper.readBoolean(); + this._pastClubDays = wrapper.readInt(); + this._pastVIPDays = wrapper.readInt(); + this._totalSeconds = wrapper.readInt(); + + return true; + } + + public get name(): string + { + return this._name; + } + + public get days(): number + { + return this._days; + } + + public get int1(): number + { + return this._int1; + } + + public get months(): number + { + return this._months; + } + + public get years(): number + { + return this._years; + } + + public get hasEverBeenMember(): boolean + { + return this._hasEverBeenMember; + } + + public get isVip(): boolean + { + return this._isVip; + } + + public get pastClubDays(): number + { + return this._pastClubDays; + } + + public get pastVIPDays(): number + { + return this._pastVIPDays; + } + + public get totalSeconds(): number + { + return this._totalSeconds; + } +} diff --git a/src/nitro/communication/messages/parser/user/wardrobe/UserWardrobePageParser.ts b/src/nitro/communication/messages/parser/user/wardrobe/UserWardrobePageParser.ts new file mode 100644 index 00000000..0ccbd67a --- /dev/null +++ b/src/nitro/communication/messages/parser/user/wardrobe/UserWardrobePageParser.ts @@ -0,0 +1,41 @@ +import { IMessageDataWrapper } from '../../../../../../core/communication/messages/IMessageDataWrapper'; +import { IMessageParser } from '../../../../../../core/communication/messages/IMessageParser'; + +export class UserWardrobePageParser implements IMessageParser +{ + private _looks: Map; + + public flush(): boolean + { + this._looks = new Map(); + + return true; + } + + public parse(wrapper: IMessageDataWrapper): boolean + { + if(!wrapper) return false; + + wrapper.readInt(); + + let totalLooks = wrapper.readInt(); + + while(totalLooks > 0) + { + const slotId = wrapper.readInt(); + const look = wrapper.readString(); + const gender = wrapper.readString(); + + this._looks.set(slotId, [look, gender]); + + totalLooks--; + } + + return true; + } + + public get looks(): Map + { + return this._looks; + } +} diff --git a/src/nitro/enums/RelationshipStatusEnum.ts b/src/nitro/enums/RelationshipStatusEnum.ts new file mode 100644 index 00000000..8c38bf9c --- /dev/null +++ b/src/nitro/enums/RelationshipStatusEnum.ts @@ -0,0 +1,10 @@ +export class RelationshipStatusEnum +{ + public static NONE: number = 0; + public static HEART: number = 1; + public static SMILE: number = 2; + public static BOBBA: number = 3; + + public static RELATIONSHIP_TYPES = [ 0, 1, 2, 3 ]; + public static RELATIONSHIP_NAMES: string[] = ['None', 'Heart', 'Smile', 'Bobba']; +} \ No newline at end of file diff --git a/src/nitro/enums/ToolbarIconEnum.ts b/src/nitro/enums/ToolbarIconEnum.ts new file mode 100644 index 00000000..e8b86858 --- /dev/null +++ b/src/nitro/enums/ToolbarIconEnum.ts @@ -0,0 +1,10 @@ +export class ToolbarIconEnum +{ + public static HOTEL_VIEW: string = 'hotel_view'; + public static HOME_ROOM: string = 'home_room'; + public static NAVIGATOR: string = 'navigator'; + public static CATALOG: string = 'catalog'; + public static INVENTORY: string = 'inventory'; + public static ME_MENU: string = 'me_menu'; + public static FRIEND_LIST: string = 'friendlist'; +} \ No newline at end of file diff --git a/src/nitro/events/NitroSettingsEvent.ts b/src/nitro/events/NitroSettingsEvent.ts new file mode 100644 index 00000000..414257bd --- /dev/null +++ b/src/nitro/events/NitroSettingsEvent.ts @@ -0,0 +1,100 @@ +import { NitroEvent } from '../../core/events/NitroEvent'; + +export class NitroSettingsEvent extends NitroEvent +{ + public static SETTINGS_UPDATED: string = 'NSE_SETTINGS_UPDATED'; + + private _volumeSystem: number; + private _volumeFurni: number; + private _volumeTrax: number; + private _oldChat: boolean; + private _roomInvites: boolean; + private _cameraFollow: boolean; + private _flags: number; + private _chatType: number; + + constructor(type: string) + { + super(type); + } + + public get volumeSystem(): number + { + return this._volumeSystem; + } + + public set volumeSystem(volume: number) + { + this._volumeSystem = volume; + } + + public get volumeFurni(): number + { + return this._volumeFurni; + } + + public set volumeFurni(volume: number) + { + this._volumeFurni = volume; + } + + public get volumeTrax(): number + { + return this._volumeTrax; + } + + public set volumeTrax(volume: number) + { + this._volumeTrax = volume; + } + + public get oldChat(): boolean + { + return this._oldChat; + } + + public set oldChat(value: boolean) + { + this._oldChat = value; + } + + public get roomInvites(): boolean + { + return this._roomInvites; + } + + public set roomInvites(value: boolean) + { + this._roomInvites = value; + } + + public get cameraFollow(): boolean + { + return this._cameraFollow; + } + + public set cameraFollow(value: boolean) + { + this._cameraFollow = value; + } + + public get flags(): number + { + return this._flags; + } + + public set flags(flags: number) + { + this._flags = flags; + } + + public get chatType(): number + { + return this._chatType; + } + + public set chatType(type: number) + { + this._chatType = type; + } +} diff --git a/src/nitro/events/NitroToolbarAnimateIconEvent.ts b/src/nitro/events/NitroToolbarAnimateIconEvent.ts new file mode 100644 index 00000000..35bd8f98 --- /dev/null +++ b/src/nitro/events/NitroToolbarAnimateIconEvent.ts @@ -0,0 +1,34 @@ +import { NitroToolbarEvent } from './NitroToolbarEvent'; + +export class NitroToolbarAnimateIconEvent extends NitroToolbarEvent +{ + public static ANIMATE_ICON: string = 'NTAIE_ANIMATE_ICON'; + + private _image: HTMLImageElement; + private _x: number; + private _y: number; + + constructor(image: HTMLImageElement, x: number, y: number) + { + super(NitroToolbarAnimateIconEvent.ANIMATE_ICON); + + this._image = image; + this._x = x; + this._y = y; + } + + public get image(): HTMLImageElement + { + return this._image; + } + + public get x(): number + { + return this._x; + } + + public get y(): number + { + return this._y; + } +} \ No newline at end of file diff --git a/src/nitro/events/NitroToolbarEvent.ts b/src/nitro/events/NitroToolbarEvent.ts new file mode 100644 index 00000000..e7aa29a1 --- /dev/null +++ b/src/nitro/events/NitroToolbarEvent.ts @@ -0,0 +1,35 @@ +import { NitroEvent } from '../../core/events/NitroEvent'; + +export class NitroToolbarEvent extends NitroEvent +{ + public static TOOLBAR_CLICK: string = 'NTE_TOOLBAR_CLICK'; + public static SELECT_OWN_AVATAR: string = 'NTE_SELECT_OWN_AVATAR'; + + private _iconId: string; + private _iconName: string; + + constructor(type: string) + { + super(type); + } + + public get iconId(): string + { + return this._iconId; + } + + public set iconId(id: string) + { + this._iconId = id; + } + + public get iconName(): string + { + return this._iconName; + } + + public set iconName(name: string) + { + this._iconName = name; + } +} \ No newline at end of file diff --git a/src/nitro/externalInterface/LegacyExternalInterface.ts b/src/nitro/externalInterface/LegacyExternalInterface.ts new file mode 100644 index 00000000..81bcade0 --- /dev/null +++ b/src/nitro/externalInterface/LegacyExternalInterface.ts @@ -0,0 +1,91 @@ +declare global +{ + interface Window + { + FlashExternalInterface?: + { + legacyTrack?: ( + category: string, + action: string, + data: unknown[] + ) => void; + logDebug?: (...params: string[]) => void; + disconnect?: (reasonCode: number, reasonString: string) => void; + logout?: () => void; + openWebPageAndMinimizeClient?: (pageUrl: string) => void; + heartBeat?: () => void; + logEventLog?: (log: string) => void; + openPage?: (pageUrl: string) => void; + closeWebPageAndRestoreClient?: () => void; + openHabblet?: (name: string, param: string) => void; + closeHabblet?: (name: string, param: string) => void; + openExternalLink?: (link: string) => void; + roomVisited?: (roomId: number) => void; + openMinimail?: (target: string) => void; + openNews?: () => void; + closeNews?: () => void; + openAvatars?: () => void; + openRoomEnterAd?: () => void; + updateFigure?: (figure: string) => void; + }; + + FlashExternalGameInterface?: + { + showGame?: (url: string) => void; + hideGame?: () => void; + }; + } +} + +export class LegacyExternalInterface +{ + public static get available(): boolean + { + return true; + } + + public static call( + method: K, + ...params: Parameters + ): ReturnType | undefined + { + if(window.top !== window) + { + window.top.postMessage('Nitro_LegacyExternalInterface' + JSON.stringify({ + method, + params + }), '*'); + } + + if(!('FlashExternalInterface' in window)) return undefined; + + const fn = window.FlashExternalInterface[method] as Function; + + return typeof fn !== 'undefined' ? fn(...params) : undefined; + } + + public static callGame( + method: K, + ...params: Parameters + ): ReturnType | undefined + { + if(window.top !== window) + { + window.top.postMessage('Nitro_LegacyExternalGameInterface' + JSON.stringify({ + method, + params + }), '*'); + } + + if(!('FlashExternalGameInterface' in window)) return undefined; + + const fn = window.FlashExternalGameInterface[method] as Function; + + return typeof fn !== 'undefined' ? fn(...params) : undefined; + } + + public static addCallback(name: string, func: Function) + { + (window as any)[name] = func; + } +} diff --git a/src/nitro/game/GameMessageHandler.ts b/src/nitro/game/GameMessageHandler.ts new file mode 100644 index 00000000..78c243a0 --- /dev/null +++ b/src/nitro/game/GameMessageHandler.ts @@ -0,0 +1,22 @@ +import { IConnection } from '../../core/communication/connections/IConnection'; +import { LoadGameUrlEvent } from '../communication/messages/incoming/game/LoadGameUrlEvent'; +import { LegacyExternalInterface } from '../externalInterface/LegacyExternalInterface'; + +export class GameMessageHandler +{ + constructor(connection: IConnection) + { + connection.addMessageEvent(new LoadGameUrlEvent(this.onLoadGameUrl.bind(this))); + } + + private onLoadGameUrl(event: LoadGameUrlEvent): void + { + if(!event) return; + + const parser = event.getParser(); + + if(!parser) return; + + LegacyExternalInterface.callGame('showGame', parser.url); + } +} \ No newline at end of file diff --git a/src/nitro/localization/BadgeBaseAndLevel.ts b/src/nitro/localization/BadgeBaseAndLevel.ts new file mode 100644 index 00000000..7341d72e --- /dev/null +++ b/src/nitro/localization/BadgeBaseAndLevel.ts @@ -0,0 +1,53 @@ +export class BadgeBaseAndLevel +{ + private _badgeId: string = ''; + private _level: number = 1; + private _base: string = ''; + + constructor(badgeId: string) + { + this._badgeId = badgeId; + + this.parseText(); + } + + private parseText():void + { + let length = (this._badgeId.length - 1); + + while(length > 0 && this.isNumber(this._badgeId.charAt(length))) length--; + + this._base = this._badgeId.substr(0, (length + 1)); + + const level = this._badgeId.substr((length + 1), this._badgeId.length); + + if(level && (level !== '')) this._level = Number.parseInt(level); + } + + private isNumber(text: string): boolean + { + const char = text.charCodeAt(0); + + return (char >= 48 && char <= 57); + } + + public get level(): number + { + return this._level; + } + + public set level(k :number) + { + this._level = Math.max(1, k); + } + + public get getBadgeId(): string + { + return this._base + this._level; + } + + public get base(): string + { + return this._base; + } +} diff --git a/src/nitro/localization/INitroLocalizationManager.ts b/src/nitro/localization/INitroLocalizationManager.ts new file mode 100644 index 00000000..0c39989d --- /dev/null +++ b/src/nitro/localization/INitroLocalizationManager.ts @@ -0,0 +1,13 @@ +import { INitroManager } from '../../core/common/INitroManager'; +export interface INitroLocalizationManager extends INitroManager +{ + getRomanNumeral(number: number): string; + getBadgeBaseAndLevel(badgeName: string): string; + getValue(key: string, doParams?: boolean): string; + getValueWithParameter(key: string, parameter: string, replacement: string): string; + getValueWithParameters(key: string, parameters: string[], replacements: string[]): string; + setValue(key: string, value: string): void; + registerParameter(key: string, parameter: string, value: string): void; + getBadgeName(key: string): string; + getBadgeDesc(key: string): string; +} diff --git a/src/nitro/localization/NitroLocalizationEvent.ts b/src/nitro/localization/NitroLocalizationEvent.ts new file mode 100644 index 00000000..5535fc22 --- /dev/null +++ b/src/nitro/localization/NitroLocalizationEvent.ts @@ -0,0 +1,12 @@ +import { NitroEvent } from '../../core/events/NitroEvent'; + +export class NitroLocalizationEvent extends NitroEvent +{ + public static LOADED: string = 'NLE_LOADED'; + public static FAILED: string = 'NLE_FAILED'; + + constructor(type: string) + { + super(type); + } +} \ No newline at end of file diff --git a/src/nitro/localization/NitroLocalizationManager.ts b/src/nitro/localization/NitroLocalizationManager.ts new file mode 100644 index 00000000..1a2ab739 --- /dev/null +++ b/src/nitro/localization/NitroLocalizationManager.ts @@ -0,0 +1,215 @@ +import { NitroManager } from '../../core/common/NitroManager'; +import { Nitro } from '../Nitro'; +import { BadgeBaseAndLevel } from './BadgeBaseAndLevel'; +import { INitroLocalizationManager } from './INitroLocalizationManager'; +import { NitroLocalizationEvent } from './NitroLocalizationEvent'; + +export class NitroLocalizationManager extends NitroManager implements INitroLocalizationManager +{ + private _definitions: Map; + private _parameters: Map>; + private _romanNumerals: string[]; + + constructor() + { + super(); + + this._definitions = new Map(); + this._parameters = new Map(); + this._romanNumerals = ['I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX', 'X', 'XI', 'XII', 'XIII', 'XIV', 'XV', 'XVI', 'XVII', 'XVIII', 'XIX', 'XX', 'XXI', 'XXII', 'XXIII', 'XXIV', 'XXV', 'XXVI', 'XXVII', 'XXVIII', 'XXIX', 'XXX']; + } + + protected onInit(): void + { + this.loadLocalizationFromURL(Nitro.instance.getConfiguration('external.texts.url')); + } + + public loadLocalizationFromURL(url: string): void + { + fetch(url) + .then(response => response.json()) + .then(data => this.onLocalizationLoaded(data)) + .catch(err => this.onLocalizationFailed(err)); + } + + private onLocalizationLoaded(data: { [index: string]: any }): void + { + if(!data) return; + + this.parseLocalization(data); + + this.events && this.events.dispatchEvent(new NitroLocalizationEvent(NitroLocalizationEvent.LOADED)); + } + + private onLocalizationFailed(error: Error): void + { + this.events && this.events.dispatchEvent(new NitroLocalizationEvent(NitroLocalizationEvent.FAILED)); + } + + private parseLocalization(data: { [index: string]: any }): void + { + if(!data) return; + + for(const key in data) this._definitions.set(key, data[key]); + } + + public getRomanNumeral(number: number): string + { + return this._romanNumerals[Math.max(0, (number - 1))]; + } + + public getBadgeBaseAndLevel(badgeName: string): string + { + const badge = new BadgeBaseAndLevel(badgeName); + + badge.level--; + + return badge.getBadgeId; + } + + public getValue(key: string, doParams: boolean = true): string + { + if(key.startsWith('${')) key = key.substr(2, (key.length - 3)); + + let value = (this._definitions.get(key) || null); + + if(value && doParams) + { + const parameters = this._parameters.get(key); + + if(parameters) + { + for(const [ parameter, replacement ] of parameters) + { + value = value.replace('%' + parameter + '%', replacement); + } + } + } + + return (value || key); + } + + public getValueWithParameter(key: string, parameter: string, replacement: string): string + { + const value = this.getValue(key, false); + + const replacedValue = value.replace('%' + parameter + '%', replacement); + + if(value.startsWith('%{')) + { + // This adds support for multi-optioned texts like + // catalog.vip.item.header.months=%{NUM_MONTHS|0 months|1 month|%% months} + // It only checks for this multi-optioned thext if the value of the key starts with %{ + + // If it does, it will create a RegEx with the provided parameter, eg. NUM_DAYS or NUM_MONTS + // Then, based on the provided replacement it searches for the resultgroup based on the replacement. + // If the replacement is not either 0, 1 - it will be assumed it will be plural. (eg. Months) + const regex = new RegExp('%{' + parameter.toUpperCase() + '\\|([^|]*)\\|([^|]*)\\|([^|]*)}'); + const result = value.match(regex); + + if(!result) return replacedValue; + + let indexKey = -1; + const replacementAsNumber = Number.parseInt(replacement); + let replace = false; + + switch(replacementAsNumber) + { + case 0: + indexKey = 1; + break; + case 1: + indexKey = 2; + break; + default: + case 2: + indexKey = 3; + replace = true; + break; + } + + + if(indexKey == -1 || typeof result[indexKey] == 'undefined') + { + return replacedValue; + } + + const valueFromResults = result[indexKey]; + + if(valueFromResults) + { + return valueFromResults.replace('%%', replacement); + } + } + + return replacedValue; + } + + public getValueWithParameters(key: string, parameters: string[], replacements: string[]): string + { + let value = this.getValue(key, false); + + for(let i = 0; i < parameters.length; i++) + { + value = value.replace('%' + parameters[i] + '%', replacements[i]); + } + + return value; + } + + public setValue(key: string, value: string): void + { + this._definitions.set(key, value); + } + + public registerParameter(key: string, parameter: string, value: string): void + { + if(!key || (key.length === 0) || !parameter || (parameter.length === 0)) return; + + let existing = this._parameters.get(key); + + if(!existing) + { + existing = new Map(); + + this._parameters.set(key, existing); + } + + existing.set(parameter, value); + } + + public getBadgeName(key: string): string + { + const local2 = new BadgeBaseAndLevel(key); + const keys = ['badge_name_' + key, 'badge_name_' + local2.base]; + const local3 = this._Str_2103(this.getExistingKey(keys)) + .replace('%roman%', this.getRomanNumeral(local2.level)); + + + + return local3; + } + + public getBadgeDesc(key: string): string + { + return ''; + } + + private getExistingKey(keys: string[]): string + { + for(const entry of keys) + { + const item = this.getValue(entry); + if(item != entry) return item; + } + + return ''; + } + + private _Str_2103(k: string): string + { + return k.replace('${', '$') + .replace('{', '$') + .replace('}', '$'); + } +} diff --git a/src/nitro/room/IGetImageListener.ts b/src/nitro/room/IGetImageListener.ts new file mode 100644 index 00000000..c272f21a --- /dev/null +++ b/src/nitro/room/IGetImageListener.ts @@ -0,0 +1,7 @@ +import { Texture } from 'pixi.js'; + +export interface IGetImageListener +{ + imageReady(id: number, texture: Texture, image?: HTMLImageElement): void; + imageFailed(id: number): void; +} \ No newline at end of file diff --git a/src/nitro/room/IRoomContentListener.ts b/src/nitro/room/IRoomContentListener.ts new file mode 100644 index 00000000..375b146b --- /dev/null +++ b/src/nitro/room/IRoomContentListener.ts @@ -0,0 +1,4 @@ +export interface IRoomContentListener +{ + onRoomContentLoaded(id: number, assetName: string, sucess: boolean): void; +} \ No newline at end of file diff --git a/src/nitro/room/IRoomCreator.ts b/src/nitro/room/IRoomCreator.ts new file mode 100644 index 00000000..bcafccf1 --- /dev/null +++ b/src/nitro/room/IRoomCreator.ts @@ -0,0 +1,58 @@ +import { IRoomInstance } from '../../room/IRoomInstance'; +import { IRoomObjectController } from '../../room/object/IRoomObjectController'; +import { IVector3D } from '../../room/utils/IVector3D'; +import { IRoomSessionManager } from '../session/IRoomSessionManager'; +import { ISessionDataManager } from '../session/ISessionDataManager'; +import { IObjectData } from './object/data/IObjectData'; +import { RoomMapData } from './object/RoomMapData'; +import { FurnitureStackingHeightMap } from './utils/FurnitureStackingHeightMap'; +import { LegacyWallGeometry } from './utils/LegacyWallGeometry'; + +export interface IRoomCreator +{ + destroyRoom(id: number): void; + getRoomInstance(roomId: number): IRoomInstance; + updateRoomInstancePlaneVisibility(roomId: number, wallVisible: boolean, floorVisible?: boolean): boolean; + updateRoomInstancePlaneThickness(roomId: number, wallThickness: number, floorThickness: number): boolean; + updateRoomInstancePlaneType(roomId: number, floorType?: string, wallType?: string, landscapeType?: string, _arg_5?: boolean): boolean; + removeRoomInstance(roomId: number): void; + createRoomInstance(roomId: number, roomMap: RoomMapData): void; + setRoomSessionOwnUser(roomId: number, objectId: number): void; + setRoomInstanceModelName(roomId: number, name: string): void; + getFurnitureStackingHeightMap(roomId: number): FurnitureStackingHeightMap; + setFurnitureStackingHeightMap(roomId: number, heightMap: FurnitureStackingHeightMap): void; + getLegacyWallGeometry(roomId: number): LegacyWallGeometry; + getRoomObject(roomId: number, objectId: number, category: number): IRoomObjectController; + getRoomObjectByIndex(roomId: number, index: number, category: number): IRoomObjectController; + getRoomObjectCursor(roomId: number): IRoomObjectController; + getRoomObjectUser(roomId: number, objectId: number): IRoomObjectController; + removeRoomObjectUser(roomId: number, objectId: number): void; + getRoomObjectFloor(roomId: number, objectId: number): IRoomObjectController; + addFurnitureFloor(roomId: number, id: number, typeId: number, location: IVector3D, direction: IVector3D, state: number, objectData: IObjectData, extra?: number, expires?: number, usagePolicy?: number, ownerId?: number, ownerName?: string, synchronized?: boolean, realRoomObject?: boolean, sizeZ?: number): boolean; + addFurnitureFloorByTypeName(roomId: number, id: number, typeName: string, location: IVector3D, direction: IVector3D, state: number, objectData: IObjectData, extra?: number, expires?: number, usagePolicy?: number, ownerId?: number, ownerName?: string, synchronized?: boolean, realRoomObject?: boolean, sizeZ?: number): boolean; + addFurnitureWall(roomId: number, id: number, typeId: number, location: IVector3D, direction: IVector3D, state: number, extra: string, expires?: number, usagePolicy?: number, ownerId?: number, ownerName?: string, realRoomObject?: boolean): boolean; + removeRoomObjectFloor(roomId: number, objectId: number, userId?: number, _arg_4?: boolean): void; + removeRoomObjectWall(roomId: number, objectId: number, userId?: number): void; + updateRoomObjectFloor(roomId: number, objectId: number, location: IVector3D, direction: IVector3D, state: number, data: IObjectData, extra?: number): boolean; + updateRoomObjectWall(roomId: number, objectId: number, location: IVector3D, direction: IVector3D, state: number, extra?: string): boolean; + updateRoomObjectWallItemData(roomId: number, objectId: number, data: string): boolean; + updateRoomObjectFloorHeight(roomId: number, objectId: number, height: number): boolean; + updateRoomObjectFloorExpiration(roomId: number, objectId: number, expires: number): boolean; + updateRoomObjectWallExpiration(roomId: number, objectId: number, expires: number): boolean; + rollRoomObjectFloor(roomId: number, objectId: number, location: IVector3D, targetLocation: IVector3D): void; + addRoomObjectUser(roomId: number, objectId: number, location: IVector3D, direction: IVector3D, headDirection: number, type: number, figure: string): boolean; + updateRoomObjectUserLocation(roomId: number, objectId: number, location: IVector3D, targetLocation: IVector3D, canStandUp?: boolean, baseY?: number, direction?: IVector3D, headDirection?: number): boolean; + updateRoomObjectUserAction(roomId: number, objectId: number, action: string, value: number, parameter?: string): boolean; + updateRoomObjectUserFigure(roomId: number, objectId: number, figure: string, gender?: string, subType?: string, isRiding?: boolean): boolean; + updateRoomObjectUserFlatControl(roomId: number, objectId: number, level: string): boolean; + updateRoomObjectUserEffect(roomId: number, objectId: number, effectId: number, delay?: number): boolean; + updateRoomObjectUserGesture(roomId: number, objectId: number, gestureId: number): boolean; + updateRoomObjectUserPetGesture(roomId: number, objectId: number, gesture: string): boolean; + updateRoomObjectUserPosture(roomId: number, objectId: number, type: string, parameter?: string): boolean; + updateRoomObjectUserOwn(roomId: number, objectId: number): void; + getPetTypeId(figure: string): number; + _Str_17722(k: number, _arg_2: string): void; + setRoomEngineGameMode(roomId: number, isPlaying: boolean): void; + sessionDataManager: ISessionDataManager; + roomSessionManager: IRoomSessionManager; +} diff --git a/src/nitro/room/IRoomEngine.ts b/src/nitro/room/IRoomEngine.ts new file mode 100644 index 00000000..bfd44afc --- /dev/null +++ b/src/nitro/room/IRoomEngine.ts @@ -0,0 +1,103 @@ +import { DisplayObject, Point, Rectangle } from 'pixi.js'; +import { INitroManager } from '../../core/common/INitroManager'; +import { IRoomManager } from '../../room/IRoomManager'; +import { IRoomObjectController } from '../../room/object/IRoomObjectController'; +import { IRoomObjectLogicFactory } from '../../room/object/logic/IRoomObjectLogicFactory'; +import { IRoomObjectVisualizationFactory } from '../../room/object/visualization/IRoomObjectVisualizationFactory'; +import { IRoomRendererFactory } from '../../room/renderer/IRoomRendererFactory'; +import { IRoomRenderingCanvas } from '../../room/renderer/IRoomRenderingCanvas'; +import { IRoomGeometry } from '../../room/utils/IRoomGeometry'; +import { IVector3D } from '../../room/utils/IVector3D'; +import { PetCustomPart } from '../avatar/pets/PetCustomPart'; +import { IRoomSessionManager } from '../session/IRoomSessionManager'; +import { ISessionDataManager } from '../session/ISessionDataManager'; +import { IGetImageListener } from './IGetImageListener'; +import { ImageResult } from './ImageResult'; +import { IObjectData } from './object/data/IObjectData'; +import { RoomMapData } from './object/RoomMapData'; +import { RoomContentLoader } from './RoomContentLoader'; +import { RoomObjectEventHandler } from './RoomObjectEventHandler'; + +export interface IRoomEngine extends INitroManager +{ + setActiveRoomId(roomId: number): void; + onRoomEngineInitalized(flag: boolean): void; + disableUpdate(flag: boolean): void; + runUpdate(): void; + createRoomInstance(roomId: number, roomMap: RoomMapData): void; + getRoomInstanceDisplay(roomId: number, id: number, width: number, height: number, scale: number): DisplayObject; + setRoomInstanceRenderingCanvasScale(roomId: number, canvasId: number, scale: number, point?: Point, offsetPoint?: Point, override?: boolean, asDelta?: boolean): void; + setRoomInstanceRenderingCanvasMask(roomId: number, canvasId: number, flag: boolean): void; + getRoomInstanceRenderingCanvas(roomId: number, canvasId?: number): IRoomRenderingCanvas; + getRoomInstanceRenderingCanvasOffset(roomId: number, canvasId?: number): Point; + setRoomInstanceRenderingCanvasOffset(roomId: number, canvasId: number, point: Point): boolean; + getRoomInstanceRenderingCanvasScale(roomId?: number, canvasId?: number): number; + initializeRoomInstanceRenderingCanvas(roomId: number, canvasId: number, width: number, height: number): void; + updateRoomInstancePlaneVisibility(roomId: number, wallVisible: boolean, floorVisible?: boolean): boolean; + updateRoomInstancePlaneThickness(roomId: number, wallThickness: number, floorThickness: number): boolean; + updateRoomInstancePlaneType(roomId: number, floorType?: string, wallType?: string, landscapeType?: string, _arg_5?: boolean): boolean; + _Str_17804(k: number, _arg_2: number, _arg_3: number, _arg_4: boolean): boolean; + getRoomInstanceGeometry(roomId: number, canvasId?: number): IRoomGeometry; + getRoomInstanceVariable(roomId: number, key: string): T; + getTotalObjectsForManager(roomId: number, category: number): number; + getRoomObject(roomId: number, objectId: number, category: number): IRoomObjectController; + getRoomObjectByIndex(roomId: number, index: number, category: number): IRoomObjectController; + removeRoomObjectFloor(roomId: number, objectId: number, userId?: number, _arg_4?: boolean): void; + removeRoomObjectWall(roomId: number, objectId: number, userId?: number): void; + removeRoomObjectUser(roomId: number, objectId: number): void; + getRoomObjectCount(roomId: number, categoryId: number): number; + getRoomObjectBoundingRectangle(roomId: number, objectId: number, category: number, canvasId: number): Rectangle; + getRoomObjectScreenLocation(roomId: number, objectId: number, objectType: number, canvasId?: number): Point; + getGenericRoomObjectImage(type: string, value: string, direction: IVector3D, scale: number, listener: IGetImageListener, bgColor?: number, extras?: string, objectData?: IObjectData, state?: number, frameCount?: number, posture?: string, originalId?: number): ImageResult; + getFurnitureFloorIconUrl(typeId: number): string; + getFurnitureFloorIcon(typeId: number, listener: IGetImageListener, extras?: string, objectData?: IObjectData): ImageResult; + getFurnitureWallIconUrl(typeId: number, extra?: string): string; + getFurnitureWallIcon(typeId: number, listener: IGetImageListener, extras?: string): ImageResult; + updateRoomObjectWallLocation(roomId: number, objectId: number, location: IVector3D): boolean; + addRoomObjectUser(roomId: number, objectId: number, location: IVector3D, direction: IVector3D, headDirection: number, type: number, figure: string): boolean; + updateRoomObjectUserLocation(roomId: number, objectId: number, location: IVector3D, targetLocation: IVector3D, canStandUp?: boolean, baseY?: number, direction?: IVector3D, headDirection?: number): boolean; + addFurnitureFloor(roomId: number, id: number, typeId: number, location: IVector3D, direction: IVector3D, state: number, objectData: IObjectData, extra?: number, expires?: number, usagePolicy?: number, ownerId?: number, ownerName?: string, synchronized?: boolean, realRoomObject?: boolean, sizeZ?: number): boolean; + addFurnitureFloorByTypeName(roomId: number, id: number, typeName: string, location: IVector3D, direction: IVector3D, state: number, objectData: IObjectData, extra?: number, expires?: number, usagePolicy?: number, ownerId?: number, ownerName?: string, synchronized?: boolean, realRoomObject?: boolean, sizeZ?: number): boolean; + addFurnitureWall(roomId: number, id: number, typeId: number, location: IVector3D, direction: IVector3D, state: number, extra: string, expires?: number, usagePolicy?: number, ownerId?: number, ownerName?: string, realRoomObject?: boolean): boolean; + initalizeTemporaryObjectsByType(type: string, _arg_2: boolean): void; + updateRoomObjectFloor(roomId: number, objectId: number, location: IVector3D, direction: IVector3D, state: number, data: IObjectData, extra?: number): boolean; + updateRoomObjectWall(roomId: number, objectId: number, location: IVector3D, direction: IVector3D, state: number, extra?: string): boolean; + updateRoomObjectUserAction(roomId: number, objectId: number, action: string, value: number, parameter?: string): boolean; + updateRoomObjectUserFigure(roomId: number, objectId: number, figure: string, gender?: string, subType?: string, isRiding?: boolean): boolean; + updateRoomObjectUserEffect(roomId: number, objectId: number, effectId: number, delay?: number): boolean; + updateRoomObjectUserGesture(roomId: number, objectId: number, gestureId: number): boolean; + updateRoomObjectUserPosture(roomId: number, objectId: number, type: string, parameter?: string): boolean; + getFurnitureFloorImage(typeId: number, direction: IVector3D, scale: number, listener: IGetImageListener, bgColor?: number, extras?: string, state?: number, frameCount?: number, objectData?: IObjectData): ImageResult; + getFurnitureWallImage(typeId: number, direction: IVector3D, scale: number, listener: IGetImageListener, bgColor?: number, extras?: string, state?: number, frameCount?: number): ImageResult; + getRoomObjectImage(roomId: number, objectId: number, category: number, direction: IVector3D, scale: number, listener: IGetImageListener, bgColor?: number): ImageResult; + getRoomObjectPetImage(typeId: number, paletteId: number, color: number, direction: IVector3D, scale: number, listener: IGetImageListener, _arg_7?: boolean, bgColor?: number, customParts?: PetCustomPart[], posture?: string): ImageResult; + selectRoomObject(roomId: number, objectId: number, objectCategory: number): void; + _Str_8675(): void; + cancelRoomObjectPlacement(): void; + getFurnitureFloorName(typeId: number): string; + useRoomObject(objectId: number, category: number): boolean; + objectInitialized(roomId: string, objectId: number, category: number): void; + changeObjectModelData(roomId: number, objectId: number, category: number, numberKey: string, numberValue: number): boolean; + changeObjectState(roomId: number, objectId: number, category: number): void; + processRoomObjectWallOperation(objectId: number, category: number, operation: string, data: Map): boolean; + processRoomObjectFloorOperation(objectId: number, category: number, operation: string, data: string): boolean; + processRoomObjectOperation(objectId: number, category: number, operation: string): boolean; + processRoomObjectPlacement(placementSource: string, id: number, category: number, typeId: number, legacyString?: string, stuffData?: IObjectData, state?: number, frameNumber?: number, posture?: string): boolean; + dispatchMouseEvent(canvasId: number, x: number, y: number, type: string, altKey: boolean, ctrlKey: boolean, shiftKey: boolean, buttonDown: boolean): void; + createRoomScreenshot(roomId: number, canvasId: number): void; + modifyRoomObjectData(objectId: number, objectCategory: number, colorHex: string, text: string): boolean; + deleteRoomObject(objectId: number, objectCategory: number): boolean; + sessionDataManager: ISessionDataManager; + roomSessionManager: IRoomSessionManager; + roomManager: IRoomManager; + objectEventHandler: RoomObjectEventHandler; + roomRendererFactory: IRoomRendererFactory; + visualizationFactory: IRoomObjectVisualizationFactory; + logicFactory: IRoomObjectLogicFactory; + roomContentLoader: RoomContentLoader; + activeRoomId: number; + ready: boolean; + disposed: boolean; + selectedAvatarId: number; + isDecorating: boolean; +} diff --git a/src/nitro/room/IRoomEngineServices.ts b/src/nitro/room/IRoomEngineServices.ts new file mode 100644 index 00000000..8c9b5676 --- /dev/null +++ b/src/nitro/room/IRoomEngineServices.ts @@ -0,0 +1,53 @@ +import { IConnection } from '../../core/communication/connections/IConnection'; +import { IEventDispatcher } from '../../core/events/IEventDispatcher'; +import { IRoomInstance } from '../../room/IRoomInstance'; +import { IRoomObjectController } from '../../room/object/IRoomObjectController'; +import { IRoomRenderingCanvas } from '../../room/renderer/IRoomRenderingCanvas'; +import { IVector3D } from '../../room/utils/IVector3D'; +import { IRoomSessionManager } from '../session/IRoomSessionManager'; +import { ISessionDataManager } from '../session/ISessionDataManager'; +import { IObjectData } from './object/data/IObjectData'; +import { FurnitureStackingHeightMap } from './utils/FurnitureStackingHeightMap'; +import { LegacyWallGeometry } from './utils/LegacyWallGeometry'; +import { SelectedRoomObjectData } from './utils/SelectedRoomObjectData'; +import { TileObjectMap } from './utils/TileObjectMap'; + +export interface IRoomEngineServices +{ + getRoomInstance(roomId: number): IRoomInstance; + getActiveRoomInstanceRenderingCanvas(): IRoomRenderingCanvas; + addRoomInstanceFloorHole(roomId: number, objectId: number): void; + removeRoomInstanceFloorHole(roomId: number, objectId: number): void; + getSelectedRoomObjectData(roomId: number): SelectedRoomObjectData; + setSelectedRoomObjectData(roomId: number, data: SelectedRoomObjectData): void; + getPlacedRoomObjectData(roomId: number): SelectedRoomObjectData; + setPlacedRoomObjectData(roomId: number, data: SelectedRoomObjectData): void; + getLegacyWallGeometry(roomId: number): LegacyWallGeometry; + getFurnitureStackingHeightMap(roomId: number): FurnitureStackingHeightMap; + getRoomObject(roomId: number, objectId: number, category: number): IRoomObjectController; + getRoomObjectByIndex(roomId: number, index: number, category: number): IRoomObjectController; + getRoomObjectCategoryForType(type: string): number; + getRoomObjectCursor(roomId: number): IRoomObjectController; + getRoomObjectSelectionArrow(roomId: number): IRoomObjectController; + addRoomObjectUser(roomId: number, objectId: number, location: IVector3D, direction: IVector3D, headDirection: number, type: number, figure: string): boolean; + addFurnitureFloor(roomId: number, id: number, typeId: number, location: IVector3D, direction: IVector3D, state: number, objectData: IObjectData, extra?: number, expires?: number, usagePolicy?: number, ownerId?: number, ownerName?: string, synchronized?: boolean, realRoomObject?: boolean, sizeZ?: number): boolean; + addFurnitureFloorByTypeName(roomId: number, id: number, typeName: string, location: IVector3D, direction: IVector3D, state: number, objectData: IObjectData, extra?: number, expires?: number, usagePolicy?: number, ownerId?: number, ownerName?: string, synchronized?: boolean, realRoomObject?: boolean, sizeZ?: number): boolean; + addFurnitureWall(roomId: number, id: number, typeId: number, location: IVector3D, direction: IVector3D, state: number, extra: string, expires?: number, usagePolicy?: number, ownerId?: number, ownerName?: string, realRoomObject?: boolean): boolean; + removeRoomObjectFloor(roomId: number, objectId: number, userId?: number, _arg_4?: boolean): void; + removeRoomObjectWall(roomId: number, objectId: number, userId?: number): void; + removeRoomObjectUser(roomId: number, objectId: number): void; + loadRoomObjectBadgeImage(roomId: number, objectId: number, objectCategory: number, badgeId: string, groupBadge?: boolean): void; + updateRoomObjectMask(roomId: number, objectId: number, _arg_?: boolean): void; + _Str_16645(objectId: number, category: number, _arg_3: boolean, instanceData?: string, stuffData?: IObjectData, state?: number, frameNumber?: number, posture?: string): void; + _Str_7972(k: boolean): void; + updateMousePointer(type: string, objectId: number, objectType: string): void; + _Str_17948(): void; + getRoomTileObjectMap(k: number): TileObjectMap; + isPlayingGame(): boolean; + connection: IConnection; + sessionDataManager: ISessionDataManager; + roomSessionManager: IRoomSessionManager; + activeRoomId: number; + events: IEventDispatcher; + isDecorating: boolean; +} \ No newline at end of file diff --git a/src/nitro/room/ISelectedRoomObjectData.ts b/src/nitro/room/ISelectedRoomObjectData.ts new file mode 100644 index 00000000..da80dc1d --- /dev/null +++ b/src/nitro/room/ISelectedRoomObjectData.ts @@ -0,0 +1,14 @@ +import { IObjectData } from './object/data/IObjectData'; + +export interface ISelectedRoomObjectData +{ + id: number; + category: number; + operation: string; + typeId: number; + _Str_4766: string; + stuffData: IObjectData; + state: number; + _Str_15896: number; + posture: string; +} diff --git a/src/nitro/room/ImageResult.ts b/src/nitro/room/ImageResult.ts new file mode 100644 index 00000000..0a67c2bd --- /dev/null +++ b/src/nitro/room/ImageResult.ts @@ -0,0 +1,18 @@ +import { RenderTexture } from 'pixi.js'; +import { TextureUtils } from '../../room/utils/TextureUtils'; + +export class ImageResult +{ + public id: number = 0; + public data: RenderTexture = null; + public image: HTMLImageElement = null; + + public getImage(): HTMLImageElement + { + if(this.image) return this.image; + + if(!this.data) return null; + + return TextureUtils.generateImage(this.data); + } +} \ No newline at end of file diff --git a/src/nitro/room/PetColorResult.ts b/src/nitro/room/PetColorResult.ts new file mode 100644 index 00000000..6a471b26 --- /dev/null +++ b/src/nitro/room/PetColorResult.ts @@ -0,0 +1,59 @@ +export class PetColorResult +{ + private static _Str_12950: string[] = ['Null', 'Black', 'White', 'Grey', 'Red', 'Orange', 'Pink', 'Green', 'Lime', 'Blue', 'Light-Blue', 'Dark-Blue', 'Yellow', 'Brown', 'Dark-Brown', 'Beige', 'Cyan', 'Purple', 'Gold']; + + private _breed: number; + private _tag: string; + private _id: string; + private _primaryColor: number; + private _secondaryColor: number; + private _isMaster: boolean; + private _layerTags: string[]; + + constructor(k: number, _arg_2: number, _arg_3: number, _arg_4: number, _arg_5: string, _arg_6: boolean, _arg_7: string[]) + { + this._layerTags = []; + this._primaryColor = (k & 0xFFFFFF); + this._secondaryColor = (_arg_2 & 0xFFFFFF); + this._breed = _arg_3; + this._tag = (((_arg_4 > -1) && (_arg_4 < PetColorResult._Str_12950.length)) ? PetColorResult._Str_12950[_arg_4] : ''); + this._id = _arg_5; + this._isMaster = _arg_6; + this._layerTags = _arg_7; + } + + public get _Str_5845(): number + { + return this._primaryColor; + } + + public get _Str_6659(): number + { + return this._secondaryColor; + } + + public get breed(): number + { + return this._breed; + } + + public get tag(): string + { + return this._tag; + } + + public get id(): string + { + return this._id; + } + + public get _Str_11964(): boolean + { + return this._isMaster; + } + + public get _Str_24801(): string[] + { + return this._layerTags; + } +} \ No newline at end of file diff --git a/src/nitro/room/RoomContentLoader.ts b/src/nitro/room/RoomContentLoader.ts new file mode 100644 index 00000000..46275f86 --- /dev/null +++ b/src/nitro/room/RoomContentLoader.ts @@ -0,0 +1,765 @@ +import { BaseTexture, ILoaderOptions, Loader, LoaderResource, Spritesheet, Texture } from 'pixi.js'; +import { IAssetData } from '../../core/asset/interfaces'; +import { NitroBundle } from '../../core/asset/NitroBundle'; +import { INitroLogger } from '../../core/common/logger/INitroLogger'; +import { NitroLogger } from '../../core/common/logger/NitroLogger'; +import { IEventDispatcher } from '../../core/events/IEventDispatcher'; +import { NitroEvent } from '../../core/events/NitroEvent'; +import { RoomContentLoadedEvent } from '../../room/events/RoomContentLoadedEvent'; +import { IRoomObject } from '../../room/object/IRoomObject'; +import { GraphicAssetCollection } from '../../room/object/visualization/utils/GraphicAssetCollection'; +import { IGraphicAssetCollection } from '../../room/object/visualization/utils/IGraphicAssetCollection'; +import { Nitro } from '../Nitro'; +import { FurnitureType } from '../session/furniture/FurnitureType'; +import { IFurnitureData } from '../session/furniture/IFurnitureData'; +import { IFurnitureDataListener } from '../session/furniture/IFurnitureDataListener'; +import { ISessionDataManager } from '../session/ISessionDataManager'; +import { IRoomContentListener } from './IRoomContentListener'; +import { RoomObjectCategory } from './object/RoomObjectCategory'; +import { RoomObjectUserType } from './object/RoomObjectUserType'; +import { RoomObjectVariable } from './object/RoomObjectVariable'; +import { RoomObjectVisualizationType } from './object/RoomObjectVisualizationType'; + +export class RoomContentLoader implements IFurnitureDataListener +{ + private static PLACE_HOLDER: string = 'place_holder'; + private static PLACE_HOLDER_WALL: string = 'place_holder_wall'; + private static PLACE_HOLDER_PET: string = 'place_holder_pet'; + private static PLACE_HOLDER_DEFAULT: string = RoomContentLoader.PLACE_HOLDER; + private static ROOM: string = 'room'; + private static TILE_CURSOR: string = 'tile_cursor'; + private static SELECTION_ARROW: string = 'selection_arrow'; + + public static LOADER_READY: string = 'RCL_LOADER_READY'; + public static MANDATORY_LIBRARIES: string[] = [ RoomContentLoader.PLACE_HOLDER, RoomContentLoader.PLACE_HOLDER_WALL, RoomContentLoader.PLACE_HOLDER_PET, RoomContentLoader.ROOM, RoomContentLoader.TILE_CURSOR, RoomContentLoader.SELECTION_ARROW ]; + + private _logger: INitroLogger; + private _stateEvents: IEventDispatcher; + private _sessionDataManager: ISessionDataManager; + private _waitingForSessionDataManager: boolean; + private _iconListener: IRoomContentListener; + private _collections: Map; + private _images: Map; + + private _events: Map; + private _activeObjects: { [index: string]: number }; + private _activeObjectTypes: Map; + private _activeObjectTypeIds: Map; + private _objectTypeAdUrls: Map; + private _wallItems: { [index: string]: number }; + private _wallItemTypes: Map; + private _wallItemTypeIds: Map; + private _furniRevisions: Map; + private _pets: { [index: string]: number }; + private _objectAliases: Map; + private _objectOriginalNames: Map; + + private _pendingContentTypes: string[]; + private _dataInitialized: boolean; + + constructor() + { + this._logger = new NitroLogger(this.constructor.name); + this._stateEvents = null; + this._sessionDataManager = null; + this._waitingForSessionDataManager = false; + this._iconListener = null; + this._collections = new Map(); + this._images = new Map(); + + this._events = new Map(); + this._activeObjects = {}; + this._activeObjectTypes = new Map(); + this._activeObjectTypeIds = new Map(); + this._objectTypeAdUrls = new Map(); + this._wallItems = {}; + this._wallItemTypes = new Map(); + this._wallItemTypeIds = new Map(); + this._furniRevisions = new Map(); + this._pets = {}; + this._objectAliases = new Map(); + this._objectOriginalNames = new Map(); + + this._pendingContentTypes = []; + this._dataInitialized = false; + } + + public initialize(events: IEventDispatcher): void + { + this._stateEvents = events; + + this.setFurnitureData(); + + for(const [ index, name ] of Nitro.instance.getConfiguration('pet.types').entries()) this._pets[name] = index; + } + + public dispose(): void + { + + } + + public setSessionDataManager(sessionData: ISessionDataManager): void + { + this._sessionDataManager = sessionData; + + if(this._waitingForSessionDataManager) + { + this._waitingForSessionDataManager = false; + + this.setFurnitureData(); + } + } + + public loadFurnitureData(): void + { + this.setFurnitureData(); + } + + private setFurnitureData(): void + { + if(!this._sessionDataManager) + { + this._waitingForSessionDataManager = true; + + return; + } + + const furnitureData = this._sessionDataManager.getAllFurnitureData(this); + + if(!furnitureData) return; + + this._sessionDataManager.removePendingFurniDataListener(this); + + this.processFurnitureData(furnitureData); + + this._stateEvents.dispatchEvent(new NitroEvent(RoomContentLoader.LOADER_READY)); + } + + private processFurnitureData(furnitureData: IFurnitureData[]): void + { + if(!furnitureData) return; + + for(const furniture of furnitureData) + { + if(!furniture) continue; + + const id = furniture.id; + + let className = furniture.className; + + if(furniture.hasIndexedColor) className = ((className + '*') + furniture.colorIndex); + + const revision = furniture.revision; + const adUrl = furniture.adUrl; + + if(adUrl && adUrl.length > 0) this._objectTypeAdUrls.set(className, adUrl); + + let name = furniture.className; + + if(furniture.type === FurnitureType.FLOOR) + { + this._activeObjectTypes.set(id, className); + this._activeObjectTypeIds.set(className, id); + + if(!this._activeObjects[name]) this._activeObjects[name] = 1; + } + + else if(furniture.type === FurnitureType.WALL) + { + if(name === 'post.it') + { + className = 'post_it'; + name = 'post_it'; + } + + if(name === 'post.it.vd') + { + className = 'post_it_vd'; + name = 'post_id_vd'; + } + + this._wallItemTypes.set(id, className); + this._wallItemTypeIds.set(className, id); + + if(!this._wallItems[name]) this._wallItems[name] = 1; + } + + const existingRevision = this._furniRevisions.get(name); + + if(revision > existingRevision) + { + this._furniRevisions.delete(name); + this._furniRevisions.set(name, revision); + } + } + } + + public getFurnitureFloorNameForTypeId(typeId: number): string + { + const type = this._activeObjectTypes.get(typeId); + + return this.removeColorIndex(type); + } + + public getFurnitureWallNameForTypeId(typeId: number, extra: string = null): string + { + let type = this._wallItemTypes.get(typeId); + + if((type === 'poster') && (extra !== null)) type = (type + extra); + + return this.removeColorIndex(type); + } + + public getFurnitureFloorColorIndex(typeId: number): number + { + const type = this._activeObjectTypes.get(typeId); + + if(!type) return -1; + + return this.getColorIndexFromName(type); + } + + public getFurnitureWallColorIndex(typeId: number): number + { + const type = this._wallItemTypes.get(typeId); + + if(!type) return -1; + + return this.getColorIndexFromName(type); + } + + private getColorIndexFromName(name: string): number + { + if(!name) return -1; + + const index = name.indexOf('*'); + + if(index === -1) return 0; + + return parseInt(name.substr(index + 1)); + } + + private removeColorIndex(name: string): string + { + if(!name) return null; + + const index = name.indexOf('*'); + + if(index === -1) return name; + + return name.substr(0, index); + } + + public getCollection(name: string): IGraphicAssetCollection + { + if(!name) return null; + + const existing = this._collections.get(name); + + if(!existing) + { + const globalCollection = Nitro.instance.core.asset.getCollection(name); + + if(globalCollection) + { + this._collections.set(name, globalCollection); + + return globalCollection; + } + + return null; + } + + return existing; + } + + public getImage(name: string): HTMLImageElement + { + if(!name) return null; + + const existing = this._images.get(name); + + if(!existing) return null; + + const image = new Image(); + + image.src = existing.src; + + return image; + } + + public addAssetToCollection(collectionName: string, assetName: string, texture: Texture): boolean + { + const collection = this.getCollection(collectionName); + + if(!collection) return false; + + return collection.addAsset(assetName, texture, true, 0, 0, false, false); + } + + private createCollection(data: IAssetData, spritesheet: Spritesheet): GraphicAssetCollection + { + if(!data || !spritesheet) return null; + + const collection = new GraphicAssetCollection(data, spritesheet); + + this._collections.set(collection.name, collection); + } + + public getPlaceholderName(type: string): string + { + const category = this.getCategoryForType(type); + + switch(category) + { + case RoomObjectCategory.FLOOR: + return RoomContentLoader.PLACE_HOLDER; + case RoomObjectCategory.WALL: + return RoomContentLoader.PLACE_HOLDER_WALL; + default: + if(this._pets[type] !== undefined) return RoomContentLoader.PLACE_HOLDER_PET; + + return RoomContentLoader.PLACE_HOLDER_DEFAULT; + } + } + + public getCategoryForType(type: string): number + { + if(!type) return RoomObjectCategory.MINIMUM; + + if(this._activeObjects[type] !== undefined) return RoomObjectCategory.FLOOR; + + if(this._wallItems[type] !== undefined) return RoomObjectCategory.WALL; + + if(this._pets[type] !== undefined) return RoomObjectCategory.UNIT; + + if(type.indexOf('poster') === 0) return RoomObjectCategory.WALL; + + if(type === 'room') return RoomObjectCategory.ROOM; + + if(type === RoomObjectUserType.USER) return RoomObjectCategory.UNIT; + + if(type === RoomObjectUserType.PET) return RoomObjectCategory.UNIT; + + if(type === RoomObjectUserType.BOT) return RoomObjectCategory.UNIT; + + if(type === RoomObjectUserType.RENTABLE_BOT) return RoomObjectCategory.UNIT; + + if(type === 'tile_cursor' || type === 'selection_arrow') return RoomObjectCategory.CURSOR; + + return RoomObjectCategory.MINIMUM; + } + + public getPetNameForType(type: number): string + { + return Nitro.instance.getConfiguration('pet.types')[type] || null; + } + + public isLoaderType(type: string): boolean + { + type = RoomObjectUserType.getRealType(type); + + if(type === RoomObjectVisualizationType.USER) return false; + + return true; + } + + public downloadImage(id: number, type: string, param: string, events: IEventDispatcher = null): boolean + { + let typeName: string = null; + let assetUrls: string[] = []; + + if(type && (type.indexOf(',') >= 0)) + { + typeName = type; + type = typeName.split(',')[0]; + } + + if(typeName) + { + assetUrls = this.getAssetUrls(typeName, param, true); + } + else + { + assetUrls = this.getAssetUrls(type, param, true); + } + + if(assetUrls && assetUrls.length) + { + const url = assetUrls[0]; + + const image = new Image(); + + image.src = url; + + image.onload = () => + { + image.onerror = null; + + this._images.set(([ type, param ].join('_')), image); + + this._iconListener.onRoomContentLoaded(id, [ type, param ].join('_'), true); + }; + + image.onerror = () => + { + image.onload = null; + + this._logger.error('Failed to download asset: ' + url); + + this._iconListener.onRoomContentLoaded(id, [ type, param ].join('_'), false); + }; + + return true; + } + + return false; + } + + public downloadAsset(type: string, events: IEventDispatcher): boolean + { + const assetUrls: string[] = this.getAssetUrls(type); + + if(!assetUrls || !assetUrls.length) return false; + + if((this._pendingContentTypes.indexOf(type) >= 0) || this.getOrRemoveEventDispatcher(type)) return false; + + this._pendingContentTypes.push(type); + this._events.set(type, events); + + const totalToDownload = assetUrls.length; + let totalDownloaded = 0; + + const onDownloaded = (loader: Loader, resource: LoaderResource, flag: boolean) => + { + if(loader) loader.destroy(); + + if(!flag) + { + this._logger.error('Failed to download asset: ' + resource.url); + + events.dispatchEvent(new RoomContentLoadedEvent(RoomContentLoadedEvent.RCLE_FAILURE, type)); + + return; + } + + totalDownloaded++; + + if(totalDownloaded === totalToDownload) + { + const events = this._events.get(type); + + if(!events) return; + + events.dispatchEvent(new RoomContentLoadedEvent(RoomContentLoadedEvent.RCLE_SUCCESS, type)); + } + }; + + for(const url of assetUrls) + { + if(!url) continue; + + const loader = new Loader(); + + const options: ILoaderOptions = { + crossOrigin: false, + xhrType: url.endsWith('.nitro') ? 'arraybuffer' : 'json' + }; + + loader + .use((resource: LoaderResource, next: Function) => this.assetLoader(loader, resource, next, onDownloaded)) + .add(url, options) + .load(); + } + + return true; + } + + private assetLoader(loader: Loader, resource: LoaderResource, next: Function, onDownloaded: Function): void + { + if(!resource || resource.error) + { + if(resource && resource.texture) resource.texture.destroy(true); + + onDownloaded(loader, resource, false); + + return; + } + + if(resource.extension === 'nitro') + { + const nitroBundle = new NitroBundle(resource.data); + const assetData = (nitroBundle.jsonFile as IAssetData); + + if(!assetData || !assetData.type) + { + onDownloaded(loader, resource, false); + + return; + } + + if(assetData.spritesheet && Object.keys(assetData.spritesheet).length) + { + const baseTexture = nitroBundle.baseTexture; + + if(!baseTexture) + { + onDownloaded(loader, resource, false); + + return; + } + + if(baseTexture.valid) + { + const spritesheet = new Spritesheet(baseTexture, assetData.spritesheet); + + spritesheet.parse(textures => + { + this.createCollection(assetData, spritesheet); + + onDownloaded(loader, resource, true); + }); + } + else + { + baseTexture.once('loaded', () => + { + baseTexture.removeAllListeners(); + + const spritesheet = new Spritesheet(baseTexture, assetData.spritesheet); + + spritesheet.parse(textures => + { + this.createCollection(assetData, spritesheet); + + onDownloaded(loader, resource, true); + }); + }); + + baseTexture.once('error', () => + { + baseTexture.removeAllListeners(); + + onDownloaded(loader, resource, false); + }); + } + + return; + } + + this.createCollection(assetData, null); + + onDownloaded(loader, resource, true); + } + + else if(resource.type === LoaderResource.TYPE.JSON) + { + const assetData = (resource.data as IAssetData); + + if(!assetData.type) + { + onDownloaded(loader, resource, false); + + return; + } + + if(assetData.spritesheet && Object.keys(assetData.spritesheet).length) + { + const imageName = (assetData.spritesheet.meta && assetData.spritesheet.meta.image); + + if(!imageName || !imageName.length) + { + onDownloaded(loader, resource, false); + + return; + } + + const imageUrl = (resource.url.substring(0, (resource.url.lastIndexOf('/') + 1)) + imageName); + const baseTexture = BaseTexture.from(imageUrl); + + if(baseTexture.valid) + { + const spritesheet = new Spritesheet(baseTexture, assetData.spritesheet); + + spritesheet.parse(textures => + { + this.createCollection(assetData, spritesheet); + + onDownloaded(loader, resource, true); + }); + } + else + { + baseTexture.once('loaded', () => + { + baseTexture.removeAllListeners(); + + const spritesheet = new Spritesheet(baseTexture, assetData.spritesheet); + + spritesheet.parse(textures => + { + this.createCollection(assetData, spritesheet); + + onDownloaded(loader, resource, true); + }); + }); + + baseTexture.once('error', () => + { + baseTexture.removeAllListeners(); + + onDownloaded(loader, resource, false); + }); + } + + return; + } + + this.createCollection(assetData, null); + + onDownloaded(loader, resource, true); + } + else + { + onDownloaded(loader, resource, false); + } + } + + public setAssetAliasName(name: string, originalName: string): void + { + this._objectAliases.set(name, originalName); + this._objectOriginalNames.set(originalName, name); + } + + private getAssetAliasName(name: string): string + { + const existing = this._objectAliases.get(name); + + if(!existing) return name; + + return existing; + } + + private getAssetOriginalName(name: string): string + { + const existing = this._objectOriginalNames.get(name); + + if(!existing) return name; + + return existing; + } + + public getAssetUrls(type: string, param: string = null, icon: boolean = false): string[] + { + switch(type) + { + case RoomContentLoader.PLACE_HOLDER: + return [ this.getAssetUrlWithRoomBase('place_holder') ]; + case RoomContentLoader.PLACE_HOLDER_WALL: + return [ this.getAssetUrlWithRoomBase('place_holder_wall') ]; + case RoomContentLoader.PLACE_HOLDER_PET: + return [ this.getAssetUrlWithRoomBase('place_holder_pet') ]; + case RoomContentLoader.ROOM: + return [ this.getAssetUrlWithRoomBase('room') ]; + case RoomContentLoader.TILE_CURSOR: + return [ this.getAssetUrlWithRoomBase('tile_cursor') ]; + case RoomContentLoader.SELECTION_ARROW: + return [ this.getAssetUrlWithRoomBase('selection_arrow') ]; + default: { + const category = this.getCategoryForType(type); + + if((category === RoomObjectCategory.FLOOR) || (category === RoomObjectCategory.WALL)) + { + const name = this.getAssetAliasName(type); + + let assetUrl = (icon ? this.getAssetUrlWithFurniIconBase(name) : this.getAssetUrlWithFurniBase(type)); + + if(icon) + { + const active = (param && (param !== '') && (this._activeObjectTypeIds.has((name + '*' + param)))); + + assetUrl = (assetUrl.replace(/%param%/gi, (active ? ('_' + param) : ''))); + } + + return [ assetUrl ]; + } + + if(category === RoomObjectCategory.UNIT) + { + return [ this.getAssetUrlWithPetBase(type) ]; + } + + return null; + } + } + } + + public getAssetIconUrl(type: string, colorIndex: string): string + { + let assetName: string = null; + let assetUrls: string[] = []; + + if(type &&( type.indexOf(',') >= 0)) + { + assetName = type; + + type = assetName.split(',')[0]; + } + + if(assetName) + { + assetUrls = this.getAssetUrls(assetName, colorIndex, true); + } + else + { + assetUrls = this.getAssetUrls(type, colorIndex, true); + } + + if(assetUrls && assetUrls.length) return assetUrls[0]; + + return null; + } + + private getAssetUrlWithRoomBase(assetName: string): string + { + return (Nitro.instance.getConfiguration('room.asset.url').replace(/%libname%/gi, assetName)); + } + + public getAssetUrlWithFurniBase(assetName: string): string + { + return (Nitro.instance.getConfiguration('furni.asset.url').replace(/%libname%/gi, assetName)); + } + + public getAssetUrlWithFurniIconBase(assetName: string): string + { + return (Nitro.instance.getConfiguration('furni.asset.icon.url').replace(/%libname%/gi, assetName)); + } + + public getAssetUrlWithPetBase(assetName: string): string + { + return (Nitro.instance.getConfiguration('pet.asset.url').replace(/%libname%/gi, assetName)); + } + + public setRoomObjectRoomId(object: IRoomObject, roomId: string): void + { + const model = object && object.model; + + if(!model) return; + + model.setValue(RoomObjectVariable.OBJECT_ROOM_ID, roomId); + } + + private getOrRemoveEventDispatcher(type: string, remove: boolean = false): IEventDispatcher + { + const existing = this._events.get(type); + + if(remove) this._events.delete(type); + + return existing; + } + + public setIconListener(listener: IRoomContentListener): void + { + this._iconListener = listener; + } +} diff --git a/src/nitro/room/RoomEngine.ts b/src/nitro/room/RoomEngine.ts new file mode 100644 index 00000000..f410e2f9 --- /dev/null +++ b/src/nitro/room/RoomEngine.ts @@ -0,0 +1,3641 @@ +import { Container, DisplayObject, Matrix, Point, Rectangle, Sprite, Texture } from 'pixi.js'; +import { IDisposable } from '../../core/common/disposable/IDisposable'; +import { IUpdateReceiver } from '../../core/common/IUpdateReceiver'; +import { NitroLogger } from '../../core/common/logger/NitroLogger'; +import { NitroManager } from '../../core/common/NitroManager'; +import { IConnection } from '../../core/communication/connections/IConnection'; +import { IMessageComposer } from '../../core/communication/messages/IMessageComposer'; +import { NitroEvent } from '../../core/events/NitroEvent'; +import { RoomObjectEvent } from '../../room/events/RoomObjectEvent'; +import { RoomObjectMouseEvent } from '../../room/events/RoomObjectMouseEvent'; +import { IRoomInstance } from '../../room/IRoomInstance'; +import { IRoomManager } from '../../room/IRoomManager'; +import { IRoomManagerListener } from '../../room/IRoomManagerListener'; +import { RoomObjectUpdateMessage } from '../../room/messages/RoomObjectUpdateMessage'; +import { IRoomObject } from '../../room/object/IRoomObject'; +import { IRoomObjectController } from '../../room/object/IRoomObjectController'; +import { IRoomObjectLogicFactory } from '../../room/object/logic/IRoomObjectLogicFactory'; +import { IRoomObjectVisualizationFactory } from '../../room/object/visualization/IRoomObjectVisualizationFactory'; +import { IRoomRenderer } from '../../room/renderer/IRoomRenderer'; +import { IRoomRendererFactory } from '../../room/renderer/IRoomRendererFactory'; +import { IRoomRenderingCanvas } from '../../room/renderer/IRoomRenderingCanvas'; +import { RoomRendererFactory } from '../../room/renderer/RoomRendererFactory'; +import { RoomInstance } from '../../room/RoomInstance'; +import { IRoomGeometry } from '../../room/utils/IRoomGeometry'; +import { IVector3D } from '../../room/utils/IVector3D'; +import { NumberBank } from '../../room/utils/NumberBank'; +import { RoomEnterEffect } from '../../room/utils/RoomEnterEffect'; +import { RoomGeometry } from '../../room/utils/RoomGeometry'; +import { Vector3d } from '../../room/utils/Vector3d'; +import { PetCustomPart } from '../avatar/pets/PetCustomPart'; +import { PetFigureData } from '../avatar/pets/PetFigureData'; +import { INitroCommunicationManager } from '../communication/INitroCommunicationManager'; +import { ToolbarIconEnum } from '../enums/ToolbarIconEnum'; +import { NitroToolbarAnimateIconEvent } from '../events/NitroToolbarAnimateIconEvent'; +import { Nitro } from '../Nitro'; +import { RoomControllerLevel } from '../session/enum/RoomControllerLevel'; +import { BadgeImageReadyEvent } from '../session/events/BadgeImageReadyEvent'; +import { RoomSessionEvent } from '../session/events/RoomSessionEvent'; +import { IRoomSessionManager } from '../session/IRoomSessionManager'; +import { ISessionDataManager } from '../session/ISessionDataManager'; +import { MouseEventType } from '../ui/MouseEventType'; +import { FurniId } from '../utils/FurniId'; +import { RoomBackgroundColorEvent } from './events/RoomBackgroundColorEvent'; +import { RoomEngineEvent } from './events/RoomEngineEvent'; +import { RoomEngineObjectEvent } from './events/RoomEngineObjectEvent'; +import { RoomObjectFurnitureActionEvent } from './events/RoomObjectFurnitureActionEvent'; +import { RoomToObjectOwnAvatarMoveEvent } from './events/RoomToObjectOwnAvatarMoveEvent'; +import { IGetImageListener } from './IGetImageListener'; +import { ImageResult } from './ImageResult'; +import { IRoomContentListener } from './IRoomContentListener'; +import { IRoomCreator } from './IRoomCreator'; +import { IRoomEngine } from './IRoomEngine'; +import { IRoomEngineServices } from './IRoomEngineServices'; +import { ObjectAvatarCarryObjectUpdateMessage } from './messages/ObjectAvatarCarryObjectUpdateMessage'; +import { ObjectAvatarChatUpdateMessage } from './messages/ObjectAvatarChatUpdateMessage'; +import { ObjectAvatarDanceUpdateMessage } from './messages/ObjectAvatarDanceUpdateMessage'; +import { ObjectAvatarEffectUpdateMessage } from './messages/ObjectAvatarEffectUpdateMessage'; +import { ObjectAvatarExperienceUpdateMessage } from './messages/ObjectAvatarExperienceUpdateMessage'; +import { ObjectAvatarExpressionUpdateMessage } from './messages/ObjectAvatarExpressionUpdateMessage'; +import { ObjectAvatarFigureUpdateMessage } from './messages/ObjectAvatarFigureUpdateMessage'; +import { ObjectAvatarFlatControlUpdateMessage } from './messages/ObjectAvatarFlatControlUpdateMessage'; +import { ObjectAvatarGestureUpdateMessage } from './messages/ObjectAvatarGestureUpdateMessage'; +import { ObjectAvatarGuideStatusUpdateMessage } from './messages/ObjectAvatarGuideStatusUpdateMessage'; +import { ObjectAvatarMutedUpdateMessage } from './messages/ObjectAvatarMutedUpdateMessage'; +import { ObjectAvatarOwnMessage } from './messages/ObjectAvatarOwnMessage'; +import { ObjectAvatarPetGestureUpdateMessage } from './messages/ObjectAvatarPetGestureUpdateMessage'; +import { ObjectAvatarPlayerValueUpdateMessage } from './messages/ObjectAvatarPlayerValueUpdateMessage'; +import { ObjectAvatarPlayingGameUpdateMessage } from './messages/ObjectAvatarPlayingGameUpdateMessage'; +import { ObjectAvatarPostureUpdateMessage } from './messages/ObjectAvatarPostureUpdateMessage'; +import { ObjectAvatarSignUpdateMessage } from './messages/ObjectAvatarSignUpdateMessage'; +import { ObjectAvatarSleepUpdateMessage } from './messages/ObjectAvatarSleepUpdateMessage'; +import { ObjectAvatarTypingUpdateMessage } from './messages/ObjectAvatarTypingUpdateMessage'; +import { ObjectAvatarUpdateMessage } from './messages/ObjectAvatarUpdateMessage'; +import { ObjectAvatarUseObjectUpdateMessage } from './messages/ObjectAvatarUseObjectUpdateMessage'; +import { ObjectDataUpdateMessage } from './messages/ObjectDataUpdateMessage'; +import { ObjectGroupBadgeUpdateMessage } from './messages/ObjectGroupBadgeUpdateMessage'; +import { ObjectHeightUpdateMessage } from './messages/ObjectHeightUpdateMessage'; +import { ObjectItemDataUpdateMessage } from './messages/ObjectItemDataUpdateMessage'; +import { ObjectModelDataUpdateMessage } from './messages/ObjectModelDataUpdateMessage'; +import { ObjectMoveUpdateMessage } from './messages/ObjectMoveUpdateMessage'; +import { ObjectRoomColorUpdateMessage } from './messages/ObjectRoomColorUpdateMessage'; +import { ObjectRoomFloorHoleUpdateMessage } from './messages/ObjectRoomFloorHoleUpdateMessage'; +import { ObjectRoomMaskUpdateMessage } from './messages/ObjectRoomMaskUpdateMessage'; +import { ObjectRoomPlanePropertyUpdateMessage } from './messages/ObjectRoomPlanePropertyUpdateMessage'; +import { ObjectRoomPlaneVisibilityUpdateMessage } from './messages/ObjectRoomPlaneVisibilityUpdateMessage'; +import { ObjectRoomUpdateMessage } from './messages/ObjectRoomUpdateMessage'; +import { ObjectStateUpdateMessage } from './messages/ObjectStateUpdateMessage'; +import { IObjectData } from './object/data/IObjectData'; +import { ObjectDataFactory } from './object/data/ObjectDataFactory'; +import { LegacyDataType } from './object/data/type/LegacyDataType'; +import { RoomLogic } from './object/logic/room/RoomLogic'; +import { RoomMapData } from './object/RoomMapData'; +import { RoomObjectCategory } from './object/RoomObjectCategory'; +import { RoomObjectUserType } from './object/RoomObjectUserType'; +import { RoomObjectVariable } from './object/RoomObjectVariable'; +import { RoomObjectVisualizationFactory } from './object/RoomObjectVisualizationFactory'; +import { RoomContentLoader } from './RoomContentLoader'; +import { RoomMessageHandler } from './RoomMessageHandler'; +import { RoomObjectEventHandler } from './RoomObjectEventHandler'; +import { RoomObjectLogicFactory } from './RoomObjectLogicFactory'; +import { RoomVariableEnum } from './RoomVariableEnum'; +import { FurnitureData } from './utils/FurnitureData'; +import { FurnitureStackingHeightMap } from './utils/FurnitureStackingHeightMap'; +import { LegacyWallGeometry } from './utils/LegacyWallGeometry'; +import { RoomCamera } from './utils/RoomCamera'; +import { RoomData } from './utils/RoomData'; +import { RoomInstanceData } from './utils/RoomInstanceData'; +import { RoomObjectBadgeImageAssetListener } from './utils/RoomObjectBadgeImageAssetListener'; +import { SelectedRoomObjectData } from './utils/SelectedRoomObjectData'; +import { SpriteDataCollector } from './utils/SpriteDataCollector'; +import { TileObjectMap } from './utils/TileObjectMap'; + +export class RoomEngine extends NitroManager implements IRoomEngine, IRoomCreator, IRoomEngineServices, IRoomManagerListener, IRoomContentListener, IUpdateReceiver, IDisposable +{ + public static ROOM_OBJECT_ID: number = -1; + public static ROOM_OBJECT_TYPE: string = 'room'; + + public static CURSOR_OBJECT_ID: number = -2; + public static CURSOR_OBJECT_TYPE: string = 'tile_cursor'; + + public static ARROW_OBJECT_ID: number = -3; + public static ARROW_OBJECT_TYPE: string = 'selection_arrow'; + + public static OVERLAY: string = 'overlay'; + public static OBJECT_ICON_SPRITE: string = 'object_icon_sprite'; + + private static DRAG_THRESHOLD: number = 15; + private static TEMPORARY_ROOM: string = 'temporary_room'; + + private _communication: INitroCommunicationManager; + private _roomRendererFactory: IRoomRendererFactory; + private _roomManager: IRoomManager; + private _visualizationFactory: IRoomObjectVisualizationFactory; + private _sessionDataManager: ISessionDataManager; + private _roomSessionManager: IRoomSessionManager; + private _roomObjectEventHandler: RoomObjectEventHandler; + private _roomMessageHandler: RoomMessageHandler; + private _roomContentLoader: RoomContentLoader; + private _ready: boolean; + private _roomContentLoaderReady: boolean; + private _imageObjectIdBank: NumberBank; + private _imageCallbacks: Map; + private _thumbnailObjectIdBank: NumberBank; + private _thumbnailCallbacks: Map; + private _activeRoomId: number; + private _activeRoomActiveCanvas: number; + private _activeRoomActiveCanvasMouseX: number; + private _activeRoomActiveCanvasMouseY: number; + private _activeRoomIsDragged: boolean; + private _activeRoomWasDragged: boolean; + private _activeRoomDragStartX: number; + private _activeRoomDragStartY: number; + private _activeRoomDragX: number; + private _activeRoomDragY: number; + private _roomDraggingAlwaysCenters: boolean; + private _roomAllowsDragging: boolean; + private _roomDatas: Map; + private _roomInstanceDatas: Map; + private _skipFurnitureCreationForNextFrame: boolean; + private _mouseCursorUpdate: boolean; + private _badgeListenerObjects: Map; + private _logicFactory: IRoomObjectLogicFactory; + + constructor(communication: INitroCommunicationManager) + { + super(); + + this._communication = communication; + this._sessionDataManager = null; + this._roomSessionManager = null; + this._roomManager = null; + this._roomObjectEventHandler = new RoomObjectEventHandler(this); + this._roomMessageHandler = new RoomMessageHandler(this); + this._roomContentLoader = new RoomContentLoader(); + this._ready = false; + this._roomContentLoaderReady = false; + + this._activeRoomId = -1; + this._activeRoomActiveCanvas = -1; + this._roomInstanceDatas = new Map(); + this._roomDatas = new Map(); + + this._roomRendererFactory = new RoomRendererFactory(); + this._visualizationFactory = new RoomObjectVisualizationFactory(); + this._logicFactory = new RoomObjectLogicFactory(); + + this._activeRoomActiveCanvasMouseX = 0; + this._activeRoomActiveCanvasMouseY = 0; + this._activeRoomIsDragged = false; + this._activeRoomWasDragged = false; + this._activeRoomDragStartX = 0; + this._activeRoomDragStartY = 0; + this._activeRoomDragX = 0; + this._activeRoomDragY = 0; + this._skipFurnitureCreationForNextFrame = false; + this._mouseCursorUpdate = false; + this._imageObjectIdBank = null; + this._imageCallbacks = new Map(); + this._thumbnailCallbacks = new Map(); + this._roomDraggingAlwaysCenters = false; + this._roomAllowsDragging = true; + this._badgeListenerObjects = new Map(); + + this.runVisibilityUpdate = this.runVisibilityUpdate.bind(this); + this.processRoomObjectEvent = this.processRoomObjectEvent.bind(this); + this.onRoomSessionEvent = this.onRoomSessionEvent.bind(this); + this.onRoomContentLoaderReadyEvent = this.onRoomContentLoaderReadyEvent.bind(this); + this.onBadgeImageReadyEvent = this.onBadgeImageReadyEvent.bind(this); + } + + public onInit(): void + { + if(this._ready) return; + + this._imageObjectIdBank = new NumberBank(1000); + this._thumbnailObjectIdBank = new NumberBank(1000); + + this._logicFactory.registerEventFunction(this.processRoomObjectEvent); + + if(this._roomManager) + { + this._roomManager.setContentLoader(this._roomContentLoader); + this._roomManager.addUpdateCategory(RoomObjectCategory.FLOOR); + this._roomManager.addUpdateCategory(RoomObjectCategory.WALL); + this._roomManager.addUpdateCategory(RoomObjectCategory.UNIT); + this._roomManager.addUpdateCategory(RoomObjectCategory.CURSOR); + this._roomManager.addUpdateCategory(RoomObjectCategory.ROOM); + } + + this._roomMessageHandler.setConnection(this._communication.connection); + + this._roomContentLoader.initialize(this.events); + this._roomContentLoader.setSessionDataManager(this._sessionDataManager); + this._roomContentLoader.setIconListener(this); + + if(this._roomSessionManager) + { + this._roomSessionManager.events.addEventListener(RoomSessionEvent.STARTED, this.onRoomSessionEvent); + this._roomSessionManager.events.addEventListener(RoomSessionEvent.ENDED, this.onRoomSessionEvent); + } + + this.events.addEventListener(RoomContentLoader.LOADER_READY, this.onRoomContentLoaderReadyEvent); + + Nitro.instance.ticker.add(this.update, this); + + document.addEventListener('visibilitychange', this.runVisibilityUpdate); + } + + public onDispose(): void + { + if(!this._ready) return; + + for(const [ key, value ] of this._roomInstanceDatas) + { + this.removeRoomInstance(key); + } + + document.removeEventListener('visibilitychange', this.runVisibilityUpdate); + + Nitro.instance.ticker.remove(this.update, this); + + if(this._roomObjectEventHandler) this._roomObjectEventHandler.dispose(); + + if(this._roomMessageHandler) this._roomMessageHandler.dispose(); + + if(this._roomContentLoader) this._roomContentLoader.dispose(); + + this.events.removeEventListener(RoomContentLoader.LOADER_READY, this.onRoomContentLoaderReadyEvent); + + if(this._roomSessionManager) + { + this._roomSessionManager.events.removeEventListener(RoomSessionEvent.STARTED, this.onRoomSessionEvent); + this._roomSessionManager.events.removeEventListener(RoomSessionEvent.ENDED, this.onRoomSessionEvent); + } + + super.onDispose(); + } + + private onRoomSessionEvent(event: RoomSessionEvent): void + { + if(!(event instanceof RoomSessionEvent)) return; + + switch(event.type) + { + case RoomSessionEvent.STARTED: + if(this._roomMessageHandler) this._roomMessageHandler.setRoomId(event.session.roomId); + return; + case RoomSessionEvent.ENDED: + if(this._roomMessageHandler) + { + this._roomMessageHandler.clearRoomId(); + this.removeRoomInstance(event.session.roomId); + } + return; + } + } + + private onRoomContentLoaderReadyEvent(event: NitroEvent): void + { + this._roomContentLoaderReady = true; + + this._roomManager.init(); + } + + public setActiveRoomId(roomId: number): void + { + this._activeRoomId = roomId; + } + + public destroyRoom(roomId: number): void + { + this.removeRoomInstance(roomId); + } + + public getRoomInstance(roomId: number): IRoomInstance + { + return (this._roomManager && this._roomManager.getRoomInstance(this.getRoomId(roomId))) || null; + } + + public removeRoomInstance(roomId: number): void + { + const instance = this.getRoomInstance(roomId); + + if(instance) + { + this._roomManager && this._roomManager.removeRoomInstance(this.getRoomId(roomId)); + } + + const existing = this._roomInstanceDatas.get(roomId); + + if(existing) + { + this._roomInstanceDatas.delete(existing.roomId); + + existing.dispose(); + } + + this.events.dispatchEvent(new RoomEngineEvent(RoomEngineEvent.DISPOSED, roomId)); + } + + public createRoomInstance(roomId: number, roomMap: RoomMapData): void + { + let floorType = '111'; + let wallType = '201'; + let landscapeType = '1'; + + if(!this._ready) + { + let data = this._roomDatas.get(roomId); + + if(data) + { + this._roomDatas.delete(roomId); + + floorType = data.floorType; + wallType = data.wallType; + landscapeType = data.landscapeType; + } + + data = new RoomData(roomId, roomMap); + + data.floorType = floorType; + data.wallType = wallType; + data.landscapeType = landscapeType; + + this._roomDatas.set(roomId, data); + + NitroLogger.log('Room Engine not initilized yet, can not create room. Room data stored for later initialization.'); + + return; + } + + if(!roomMap) + { + NitroLogger.log('Room property messages received before floor height map, will initialize when floor height map received.'); + + return; + } + + const data = this._roomDatas.get(roomId); + + if(data) + { + this._roomDatas.delete(roomId); + + if(data.floorType) floorType = data.floorType; + + if(data.wallType) wallType = data.wallType; + + if(data.landscapeType) landscapeType = data.landscapeType; + } + + const instance = this.setupRoomInstance(roomId, roomMap, floorType, wallType, landscapeType, this.getRoomInstanceModelName(roomId)); + + if(!instance) return; + + if(roomMap.restrictsDragging) + { + this._roomAllowsDragging = false; + } + else + { + this._roomAllowsDragging = true; + } + + this.events.dispatchEvent(new RoomEngineEvent(RoomEngineEvent.INITIALIZED, roomId)); + } + + private setupRoomInstance(roomId: number, roomMap: RoomMapData, floorType: string, wallType: string, landscapeType: string, worldType: string): IRoomInstance + { + if(!this._ready || !this._roomManager) return; + + const instance = this._roomManager.createRoomInstance(this.getRoomId(roomId)); + + if(!instance) return null; + + const category = RoomObjectCategory.ROOM; + + const roomObject = instance.createRoomObjectAndInitalize(RoomEngine.ROOM_OBJECT_ID, RoomEngine.ROOM_OBJECT_TYPE, category) as IRoomObjectController; + + instance.model.setValue(RoomVariableEnum.ROOM_IS_PUBLIC, 0); + instance.model.setValue(RoomVariableEnum.ROOM_Z_SCALE, 1); + + if(roomMap) + { + instance.model.setValue(RoomVariableEnum.RESTRICTS_DRAGGING, roomMap.restrictsDragging); + instance.model.setValue(RoomVariableEnum.RESTRICTS_SCALING, roomMap.restrictsScaling); + instance.model.setValue(RoomVariableEnum.RESTRICTED_SCALE, roomMap.restrictedScale); + + const dimensions = roomMap.dimensions; + + if(dimensions) + { + const minX = roomMap.dimensions.minX; + const maxX = roomMap.dimensions.maxX; + const minY = roomMap.dimensions.minY; + const maxY = roomMap.dimensions.maxY; + + instance.model.setValue(RoomVariableEnum.ROOM_MIN_X, minX); + instance.model.setValue(RoomVariableEnum.ROOM_MAX_X, maxX); + instance.model.setValue(RoomVariableEnum.ROOM_MIN_Y, minY); + instance.model.setValue(RoomVariableEnum.ROOM_MAX_Y, maxY); + + const seed = ((((minX * 423) + (maxX * 671)) + (minY * 913)) + (maxY * 7509)); + + if(roomObject && roomObject.model) roomObject.model.setValue(RoomObjectVariable.ROOM_RANDOM_SEED, seed); + } + } + + const logic = (roomObject && roomObject.logic as RoomLogic) || null; + + if(logic) + { + logic.initialize(roomMap); + + if(floorType) + { + logic.processUpdateMessage(new ObjectRoomUpdateMessage(ObjectRoomUpdateMessage.ROOM_FLOOR_UPDATE, floorType)); + instance.model.setValue(RoomObjectVariable.ROOM_FLOOR_TYPE, floorType); + } + + if(wallType) + { + logic.processUpdateMessage(new ObjectRoomUpdateMessage(ObjectRoomUpdateMessage.ROOM_WALL_UPDATE, wallType)); + instance.model.setValue(RoomObjectVariable.ROOM_WALL_TYPE, wallType); + } + + if(landscapeType) + { + logic.processUpdateMessage(new ObjectRoomUpdateMessage(ObjectRoomUpdateMessage.ROOM_LANDSCAPE_UPDATE, landscapeType)); + instance.model.setValue(RoomObjectVariable.ROOM_LANDSCAPE_TYPE, landscapeType); + } + } + + if(roomMap && roomMap.doors.length) + { + let doorIndex = 0; + + while(doorIndex < roomMap.doors.length) + { + const door = roomMap.doors[doorIndex]; + + if(door) + { + const doorX = door.x; + const doorY = door.y; + const doorZ = door.z; + const doorDir = door.dir; + const maskType = ObjectRoomMaskUpdateMessage.DOOR; + const maskId = 'door_' + doorIndex; + const maskLocation = new Vector3d(doorX, doorY, doorZ); + + logic.processUpdateMessage(new ObjectRoomMaskUpdateMessage(ObjectRoomMaskUpdateMessage.ADD_MASK, maskId, maskType, maskLocation, ObjectRoomMaskUpdateMessage.HOLE)); + + if((doorDir === 90) || (doorDir === 180)) + { + if(doorDir === 90) + { + instance.model.setValue(RoomObjectVariable.ROOM_DOOR_X, (doorX - 0.5)); + instance.model.setValue(RoomObjectVariable.ROOM_DOOR_Y, doorY); + } + + if(doorDir === 180) + { + instance.model.setValue(RoomObjectVariable.ROOM_DOOR_X, doorX); + instance.model.setValue(RoomObjectVariable.ROOM_DOOR_Y, (doorY - 0.5)); + } + + instance.model.setValue(RoomObjectVariable.ROOM_DOOR_Z, doorZ); + instance.model.setValue(RoomObjectVariable.ROOM_DOOR_DIR, doorDir); + } + } + + doorIndex++; + } + } + + instance.createRoomObjectAndInitalize(RoomEngine.CURSOR_OBJECT_ID, RoomEngine.CURSOR_OBJECT_TYPE, RoomObjectCategory.CURSOR); + //instance.createRoomObjectAndInitalize(RoomEngine.ARROW_OBJECT_ID, RoomEngine.ARROW_OBJECT_TYPE, RoomObjectCategory.CURSOR); + + return instance; + } + + public getRoomInstanceDisplay(roomId: number, id: number, width: number, height: number, scale: number): DisplayObject + { + const instance = this.getRoomInstance(roomId); + + if(!instance) return null; + + let renderer = instance.renderer as IRoomRenderer; + + if(!renderer) + { + renderer = this._roomRendererFactory.createRenderer(); + + if(!renderer) return null; + } + + renderer.roomObjectVariableAccurateZ = RoomObjectVariable.OBJECT_ACCURATE_Z_VALUE; + + instance.setRenderer(renderer); + + const canvas = renderer.createCanvas(id, width, height, scale); + + if(!canvas) return null; + + const restrictedScaling = instance.model.getValue(RoomVariableEnum.RESTRICTS_SCALING); + + if(restrictedScaling) + { + let restrictedScale = instance.model.getValue(RoomVariableEnum.RESTRICTED_SCALE); + + if(!restrictedScale) restrictedScale = 1; + + canvas.setScale(restrictedScale); + + canvas.restrictsScaling = true; + } + else + { + canvas.restrictsScaling = false; + } + + canvas.setMouseListener(this._roomObjectEventHandler); + + if(canvas.geometry) + { + canvas.geometry.z_scale = instance.model.getValue(RoomVariableEnum.ROOM_Z_SCALE); + + const doorX = instance.model.getValue(RoomObjectVariable.ROOM_DOOR_X); + const doorY = instance.model.getValue(RoomObjectVariable.ROOM_DOOR_Y); + const doorZ = instance.model.getValue(RoomObjectVariable.ROOM_DOOR_Z); + const doorDirection = instance.model.getValue(RoomObjectVariable.ROOM_DOOR_DIR); + const vector = new Vector3d(doorX, doorY, doorZ); + + let direction: IVector3D = null; + + if(doorDirection === 90) direction = new Vector3d(-2000, 0, 0); + + if(doorDirection === 180) direction = new Vector3d(0, -2000, 0); + + canvas.geometry.setDisplacement(vector, direction); + + const displayObject = (canvas.master as Container); + + if(displayObject) + { + const overlay = Sprite.from(Texture.EMPTY); + + overlay.name = RoomEngine.OVERLAY; + overlay.interactive = false; + + displayObject.addChild(overlay); + } + } + + return canvas.master; + } + + public setRoomInstanceRenderingCanvasMask(roomId: number, canvasId: number, flag: boolean): void + { + const roomCanvas = this.getRoomInstanceRenderingCanvas(roomId, canvasId); + + if(roomCanvas) roomCanvas.setMask(flag); + } + + public setRoomInstanceRenderingCanvasScale(roomId: number, canvasId: number, scale: number, point: Point = null, offsetPoint: Point = null, override: boolean = false, asDelta: boolean = false): void + { + const roomCanvas = this.getRoomInstanceRenderingCanvas(roomId, canvasId); + + if(roomCanvas) + { + if(roomCanvas.restrictsScaling && !override) return; + + roomCanvas.setScale(scale, point, offsetPoint, override, asDelta); + + this.events.dispatchEvent(new RoomEngineEvent(RoomEngineEvent.ROOM_ZOOMED, roomId)); + } + } + + public getRoomInstanceRenderingCanvas(roomId: number, canvasId: number = -1): IRoomRenderingCanvas + { + const instance = this.getRoomInstance(roomId); + + if(!instance) return null; + + const renderer = instance.renderer as IRoomRenderer; + + if(!renderer) return null; + + if(canvasId === -1) canvasId = this._activeRoomActiveCanvas; + + const canvas = renderer.getCanvas(canvasId); + + if(!canvas) return null; + + return canvas; + } + + public getActiveRoomInstanceRenderingCanvas(): IRoomRenderingCanvas + { + return this.getRoomInstanceRenderingCanvas(this._activeRoomId, this._activeRoomActiveCanvas); + } + + public getRoomInstanceRenderingCanvasOffset(roomId: number, canvasId: number = -1): Point + { + if(canvasId === -1) canvasId = this._activeRoomActiveCanvas; + + const renderingCanvas = this.getRoomInstanceRenderingCanvas(roomId, canvasId); + + if(!renderingCanvas) return null; + + return new Point(renderingCanvas.screenOffsetX, renderingCanvas.screenOffsetY); + } + + public setRoomInstanceRenderingCanvasOffset(roomId: number, canvasId: number, point: Point): boolean + { + const renderingCanvas = this.getRoomInstanceRenderingCanvas(roomId, canvasId); + + if(!renderingCanvas || !point) return false; + + renderingCanvas.screenOffsetX = point.x; + renderingCanvas.screenOffsetY = point.y; + + return true; + } + + public getRoomInstanceRenderingCanvasScale(roomId: number = -1000, canvasId: number = -1): number + { + if(roomId === -1000) roomId = this._activeRoomId; + + if(canvasId === -1) canvasId = this._activeRoomActiveCanvas; + + const canvas = this.getRoomInstanceRenderingCanvas(roomId, canvasId); + + if(!canvas) return 1; + + return canvas.scale; + } + + public initializeRoomInstanceRenderingCanvas(roomId: number, canvasId: number, width: number, height: number): void + { + const canvas = this.getRoomInstanceRenderingCanvas(roomId, canvasId); + + if(!canvas) return; + + canvas.initialize(width, height); + } + + public getRoomInstanceGeometry(roomId: number, canvasId: number = -1): IRoomGeometry + { + const instance = this.getRoomInstance(roomId); + + if(!instance) return null; + + const renderer = instance.renderer as IRoomRenderer; + + if(!renderer) return null; + + if(canvasId === -1) canvasId = this._activeRoomActiveCanvas; + + const canvas = renderer.getCanvas(canvasId); + + if(!canvas) return null; + + return canvas.geometry; + } + + public getRoomInstanceVariable(roomId: number, key: string): T + { + const instance = this.getRoomInstance(roomId); + + if(!instance) return null; + + return ((instance.model && instance.model.getValue(key)) || null); + } + + public updateRoomInstancePlaneVisibility(roomId: number, wallVisible: boolean, floorVisible: boolean = true): boolean + { + const object = this.getRoomOwnObject(roomId); + + if(!object) return false; + + object.processUpdateMessage(new ObjectRoomPlaneVisibilityUpdateMessage(ObjectRoomPlaneVisibilityUpdateMessage.WALL_VISIBILITY, wallVisible)); + object.processUpdateMessage(new ObjectRoomPlaneVisibilityUpdateMessage(ObjectRoomPlaneVisibilityUpdateMessage.FLOOR_VISIBILITY, floorVisible)); + + return true; + } + + public updateRoomInstancePlaneThickness(roomId: number, wallThickness: number, floorThickness: number): boolean + { + const object = this.getRoomOwnObject(roomId); + + if(!object) return false; + + object.processUpdateMessage(new ObjectRoomPlanePropertyUpdateMessage(ObjectRoomPlanePropertyUpdateMessage.WALL_THICKNESS, wallThickness)); + object.processUpdateMessage(new ObjectRoomPlanePropertyUpdateMessage(ObjectRoomPlanePropertyUpdateMessage.FLOOR_THICKNESS, floorThickness)); + + return true; + } + + public updateRoomInstancePlaneType(roomId: number, floorType: string = null, wallType: string = null, landscapeType: string = null, _arg_5: boolean = false): boolean + { + const roomObject = this.getRoomOwnObject(roomId); + const roomInstance = this.getRoomInstance(roomId); + + if(!roomObject) + { + let roomData = this._roomDatas.get(roomId); + + if(!roomData) + { + roomData = new RoomData(roomId, null); + + this._roomDatas.set(roomId, roomData); + } + + if(floorType) roomData.floorType = floorType; + + if(wallType) roomData.wallType = wallType; + + if(landscapeType) roomData.landscapeType = landscapeType; + + return true; + } + + if(floorType) + { + if(roomInstance && !_arg_5) roomInstance.model.setValue(RoomObjectVariable.ROOM_FLOOR_TYPE, floorType); + + roomObject.processUpdateMessage(new ObjectRoomUpdateMessage(ObjectRoomUpdateMessage.ROOM_FLOOR_UPDATE, floorType)); + } + + if(wallType) + { + if(roomInstance && !_arg_5) roomInstance.model.setValue(RoomObjectVariable.ROOM_WALL_TYPE, wallType); + + roomObject.processUpdateMessage(new ObjectRoomUpdateMessage(ObjectRoomUpdateMessage.ROOM_WALL_UPDATE, wallType)); + } + + if(landscapeType) + { + if(roomInstance && !_arg_5) roomInstance.model.setValue(RoomObjectVariable.ROOM_LANDSCAPE_TYPE, landscapeType); + + roomObject.processUpdateMessage(new ObjectRoomUpdateMessage(ObjectRoomUpdateMessage.ROOM_LANDSCAPE_UPDATE, landscapeType)); + } + + return true; + } + + public _Str_17804(k: number, _arg_2: number, _arg_3: number, _arg_4: boolean): boolean + { + const roomObject = this.getRoomOwnObject(k); + + if(!roomObject || !roomObject.logic) return false; + + const event = new ObjectRoomColorUpdateMessage(ObjectRoomColorUpdateMessage.BACKGROUND_COLOR, _arg_2, _arg_3, _arg_4); + + roomObject.logic.processUpdateMessage(event); + + this.events.dispatchEvent(new RoomBackgroundColorEvent(k, _arg_2, _arg_3, _arg_4)); + + return true; + } + + public addRoomInstanceFloorHole(roomId: number, objectId: number): void + { + if(objectId < 0) return; + + const roomOwnObject = this.getRoomOwnObject(roomId); + const roomObject = this.getRoomObjectFloor(roomId, objectId); + + if(roomOwnObject && roomOwnObject.logic && roomObject && roomObject.model) + { + const location = roomObject.getLocation(); + const sizeX = roomObject.model.getValue(RoomObjectVariable.FURNITURE_SIZE_X); + const sizeY = roomObject.model.getValue(RoomObjectVariable.FURNITURE_SIZE_Y); + + roomOwnObject.processUpdateMessage(new ObjectRoomFloorHoleUpdateMessage(ObjectRoomFloorHoleUpdateMessage.ADD, objectId, location.x, location.y, sizeX, sizeY)); + } + } + + public removeRoomInstanceFloorHole(roomId: number, objectId: number): void + { + if(objectId < 0) return; + + const roomOwnObject = this.getRoomOwnObject(roomId); + + if(roomOwnObject) + { + roomOwnObject.processUpdateMessage(new ObjectRoomFloorHoleUpdateMessage(ObjectRoomFloorHoleUpdateMessage.REMOVE, objectId)); + } + } + + public setRoomEngineGameMode(roomId: number, isPlaying: boolean): void + { + const roomInstance = this.getRoomInstance(roomId); + + if(!roomInstance) return; + + const mode = isPlaying ? 1 : 0; + + roomInstance.model.setValue(RoomVariableEnum.IS_PLAYING_GAME, mode); + + if(mode === 0) + { + this.events.dispatchEvent(new RoomEngineEvent(RoomEngineEvent.NORMAL_MODE, roomId)); + } + else + { + this.events.dispatchEvent(new RoomEngineEvent(RoomEngineEvent.GAME_MODE, roomId)); + } + } + + public isRoomIdPlayingGame(roomId: number): boolean + { + const roomInstance = this.getRoomInstance(roomId); + + if(!roomInstance) return false; + + return (roomInstance.model.getValue(RoomVariableEnum.IS_PLAYING_GAME) > 0); + } + + public isPlayingGame(): boolean + { + return this.isRoomIdPlayingGame(this._activeRoomId); + } + + public disableUpdate(flag: boolean): void + { + if(flag) + { + Nitro.instance.ticker.remove(this.update, this); + } + else + { + Nitro.instance.ticker.remove(this.update, this); + Nitro.instance.ticker.add(this.update, this); + } + } + + public runUpdate(): void + { + this.update(1); + } + + public runVisibilityUpdate(): void + { + if(!document.hidden) this.update(1, true); + } + + public update(time: number, update: boolean = false): void + { + if(!this._roomManager) return; + + time = Nitro.instance.time; + + RoomEnterEffect.turnVisualizationOn(); + + this.processPendingFurniture(); + + this._roomManager.update(time, update); + + this._Str_22919(time); + + if(this._mouseCursorUpdate) this.setPointer(); + + RoomEnterEffect.turnVisualizationOff(); + } + + private setPointer(): void + { + this._mouseCursorUpdate = false; + + const instanceData = this.getRoomInstanceData(this._activeRoomId); + + if(instanceData && instanceData._Str_22598()) + { + document.body.style.cursor = 'pointer'; + } + else + { + document.body.style.cursor = 'auto'; + } + } + + private processPendingFurniture(): void + { + if(this._skipFurnitureCreationForNextFrame) + { + this._skipFurnitureCreationForNextFrame = false; + + return; + } + + const startTime = new Date().valueOf(); + const furniturePerTick = 5; + const hasTickLimit = true; + + for(const instanceData of this._roomInstanceDatas.values()) + { + if(!instanceData) continue; + + let pendingData: FurnitureData = null; + let totalFurnitureAdded = 0; + let furnitureAdded = false; + + while((pendingData = instanceData.getNextPendingFurnitureFloor())) + { + furnitureAdded = this.processPendingFurnitureFloor(instanceData.roomId, pendingData.id, pendingData); + + if(hasTickLimit) + { + if(!(++totalFurnitureAdded % furniturePerTick)) + { + const time = new Date().valueOf(); + + if((time - startTime) >= 40) + { + this._skipFurnitureCreationForNextFrame = true; + + break; + } + } + } + } + + while(!this._skipFurnitureCreationForNextFrame && (pendingData = instanceData.getNextPendingFurnitureWall())) + { + furnitureAdded = this.processPendingFurnitureWall(instanceData.roomId, pendingData.id, pendingData); + + if(hasTickLimit) + { + if(!(++totalFurnitureAdded % furniturePerTick)) + { + const time = new Date().valueOf(); + + if((time - startTime) >= 40) + { + this._skipFurnitureCreationForNextFrame = true; + + break; + } + } + } + } + + if(furnitureAdded && this._roomManager) + { + const roomInstance = this._roomManager.getRoomInstance(this.getRoomId(instanceData.roomId)) as RoomInstance; + + if(!roomInstance.hasUninitializedObjects()) this.objectsInitialized(instanceData.roomId.toString()); + } + + if(this._skipFurnitureCreationForNextFrame) return; + } + } + + public onRoomEngineInitalized(flag: boolean): void + { + if(!flag) return; + + this._ready = true; + + this.events.dispatchEvent(new RoomEngineEvent(RoomEngineEvent.ENGINE_INITIALIZED, 0)); + + for(const roomData of this._roomDatas.values()) + { + if(!roomData) continue; + + this.createRoomInstance(roomData.roomId, roomData.data); + } + } + + private processPendingFurnitureFloor(roomId: number, id: number, data: FurnitureData): boolean + { + if(!data) + { + const instanceData = this.getRoomInstanceData(roomId); + + if(instanceData) data = instanceData.getPendingFurnitureFloor(id); + + if(!data) return false; + } + + let type = data.type; + let didLoad = false; + + if(!type) + { + type = this.getFurnitureFloorName(data.typeId); + didLoad = true; + + } + + const object = this.createRoomObjectFloor(roomId, id, type); + + if(!object) return false; + + const model = object.model; + + if(model) + { + model.setValue(RoomObjectVariable.FURNITURE_COLOR, this.getFurnitureFloorColorIndex(data.typeId)); + model.setValue(RoomObjectVariable.FURNITURE_TYPE_ID, data.typeId); + model.setValue(RoomObjectVariable.FURNITURE_REAL_ROOM_OBJECT, (data.realRoomObject ? 1 : 0)); + model.setValue(RoomObjectVariable.FURNITURE_EXPIRY_TIME, data.expiryTime); + model.setValue(RoomObjectVariable.FURNITURE_EXPIRTY_TIMESTAMP, Nitro.instance.time); + model.setValue(RoomObjectVariable.FURNITURE_USAGE_POLICY, data.usagePolicy); + model.setValue(RoomObjectVariable.FURNITURE_OWNER_ID, data.ownerId); + model.setValue(RoomObjectVariable.FURNITURE_OWNER_NAME, data.ownerName); + } + + if(!this.updateRoomObjectFloor(roomId, id, data.location, data.direction, data.state, data.data, data.extra)) return false; + + if(data.sizeZ >= 0) + { + if(!this.updateRoomObjectFloorHeight(roomId, id, data.sizeZ)) return false; + } + + if(this.events) this.events.dispatchEvent(new RoomEngineObjectEvent(RoomEngineObjectEvent.ADDED, roomId, id, RoomObjectCategory.FLOOR)); + + const selectedRoomObjectData = this.getPlacedRoomObjectData(roomId); + + if(selectedRoomObjectData && (selectedRoomObjectData.id === id) && (selectedRoomObjectData.category === RoomObjectCategory.FLOOR)) + { + this.selectRoomObject(roomId, id, RoomObjectCategory.FLOOR); + } + + if(object.isReady && data.synchronized) this._Str_21543(roomId, object); + + return true; + } + + private processPendingFurnitureWall(roomId: number, id: number, data: FurnitureData): boolean + { + if(!data) + { + const instanceData = this.getRoomInstanceData(roomId); + + if(instanceData) data = instanceData.getPendingFurnitureWall(id); + + if(!data) return false; + } + + let extra = ''; + + if(data.data) extra = data.data.getLegacyString(); + + let type = this.getFurnitureWallName(data.typeId, extra); + + if(!type) type = ''; + + const object = this.createRoomObjectWall(roomId, id, type); + + if(!object) return false; + + const model = object.model; + + if(model) + { + model.setValue(RoomObjectVariable.FURNITURE_COLOR, this.getFurnitureWallColorIndex(data.typeId)); + model.setValue(RoomObjectVariable.FURNITURE_TYPE_ID, data.typeId); + model.setValue(RoomObjectVariable.FURNITURE_REAL_ROOM_OBJECT, (data.realRoomObject ? 1 : 0)); + model.setValue(RoomObjectVariable.OBJECT_ACCURATE_Z_VALUE, 1); + model.setValue(RoomObjectVariable.FURNITURE_EXPIRY_TIME, data.expiryTime); + model.setValue(RoomObjectVariable.FURNITURE_EXPIRTY_TIMESTAMP, Nitro.instance.time); + model.setValue(RoomObjectVariable.FURNITURE_USAGE_POLICY, data.usagePolicy); + model.setValue(RoomObjectVariable.FURNITURE_OWNER_ID, data.ownerId); + model.setValue(RoomObjectVariable.FURNITURE_OWNER_NAME, data.ownerName); + } + + if(!this.updateRoomObjectWall(roomId, id, data.location, data.direction, data.state, extra)) return false; + + if(this.events) this.events.dispatchEvent(new RoomEngineObjectEvent(RoomEngineObjectEvent.ADDED, roomId, id, RoomObjectCategory.WALL)); + + const selectedRoomObjectData = this.getPlacedRoomObjectData(roomId); + + if(selectedRoomObjectData && (Math.abs(selectedRoomObjectData.id) === id) && (selectedRoomObjectData.category === RoomObjectCategory.WALL)) + { + this.selectRoomObject(roomId, id, RoomObjectCategory.WALL); + } + + return true; + } + + public setRoomSessionOwnUser(roomId: number, objectId: number): void + { + if(!this._roomSessionManager) return; + + const session = this._roomSessionManager.getSession(roomId); + + if(session) + { + session.setOwnRoomIndex(objectId); + } + + const camera = this.getRoomCamera(roomId); + + if(camera) + { + camera._Str_10760 = objectId; + camera._Str_16562 = RoomObjectCategory.UNIT; + + camera._Str_19465(this._Str_19549); + } + } + + private get _Str_19549(): number + { + return 1000; + //return (getBoolean("room.camera.follow_user")) ? 1000 : 0; + } + + private _Str_22919(time: number): void + { + for(const instanceData of this._roomInstanceDatas.values()) + { + if(!instanceData) continue; + + const camera = instanceData.roomCamera; + + if(!camera) continue; + + const object = this.getRoomObject(instanceData.roomId, camera._Str_10760, camera._Str_16562); + + if(!object) continue; + + if((instanceData.roomId !== this._activeRoomId) || !this._activeRoomIsDragged) + { + this._Str_25242(instanceData.roomId, 1, object.getLocation(), time); + } + } + + const canvas = this.getRoomInstanceRenderingCanvas(this._activeRoomId, 1); + + if(canvas) + { + if(this._activeRoomIsDragged) + { + canvas.screenOffsetX = (canvas.screenOffsetX + this._activeRoomDragX); + canvas.screenOffsetY = (canvas.screenOffsetY + this._activeRoomDragY); + + this._activeRoomDragX = 0; + this._activeRoomDragY = 0; + } + } + } + + private _Str_25242(roomId: number, canvasId: number, objectLocation: IVector3D, time: number): void + { + const renderingCanvas = this.getRoomInstanceRenderingCanvas(roomId, canvasId); + const instanceData = this.getRoomInstanceData(roomId); + + if(!renderingCanvas || !instanceData || (renderingCanvas.scale !== 1)) return; + + const roomGeometry = (renderingCanvas.geometry as RoomGeometry); + const roomCamera = instanceData.roomCamera; + const roomInstance = this.getRoomInstance(roomId); + + if(!roomGeometry || !roomCamera || !roomInstance) return; + + const canvasRectangle = this._Str_25261(roomId, canvasId); + + if(!canvasRectangle) return; + + let _local_10 = (Math.floor(objectLocation.z) + 1); + const width = Math.round(canvasRectangle.width); + const height = Math.round(canvasRectangle.height); + const bounds = this.getCanvasBoundingRectangle(canvasId); + + if(bounds && ((bounds.right < 0) || (bounds.bottom < 0) || (bounds.left >= width) || (bounds.top >= height))) + { + roomCamera.reset(); + } + + if((roomCamera._Str_7609 !== width) || (roomCamera._Str_7902 !== height) || (roomCamera.scale !== roomGeometry.scale) || (roomCamera._Str_16377 !== roomGeometry.updateId) || !Vector3d.isEqual(objectLocation, roomCamera._Str_16185) || roomCamera._Str_12536) + { + roomCamera._Str_16185 = objectLocation; + + const _local_15 = new Vector3d(); + + _local_15.assign(objectLocation); + + _local_15.x = Math.round(_local_15.x); + _local_15.y = Math.round(_local_15.y); + + const _local_16 = (roomInstance.model.getValue(RoomVariableEnum.ROOM_MIN_X) - 0.5); + const _local_17 = (roomInstance.model.getValue(RoomVariableEnum.ROOM_MIN_Y) - 0.5); + const _local_18 = (roomInstance.model.getValue(RoomVariableEnum.ROOM_MAX_X) + 0.5); + const _local_19 = (roomInstance.model.getValue(RoomVariableEnum.ROOM_MAX_Y) + 0.5); + const _local_20 = Math.round(((_local_16 + _local_18) / 2)); + const _local_21 = Math.round(((_local_17 + _local_19) / 2)); + const _local_22 = 2; + let _local_23 = new Point((_local_15.x - _local_20), (_local_15.y - _local_21)); + const _local_24 = (roomGeometry.scale / Math.sqrt(2)); + const _local_25 = (_local_24 / 2); + const _local_26 = new Matrix(); + _local_26.rotate(((-(roomGeometry.direction.x + 90) / 180) * Math.PI)); + _local_23 = _local_26.apply(_local_23); + _local_23.y = (_local_23.y * (_local_25 / _local_24)); + const _local_27 = (((canvasRectangle.width / 2) / _local_24) - 1); + const _local_28 = (((canvasRectangle.height / 2) / _local_25) - 1); + + let _local_29 = 0; + let _local_30 = 0; + let _local_31 = 0; + let _local_32 = 0; + let _local_33 = roomGeometry.getScreenPoint(new Vector3d(_local_20, _local_21, _local_22)); + + if(!_local_33) return; + + _local_33.x = (_local_33.x + Math.round((canvasRectangle.width / 2))); + _local_33.y = (_local_33.y + Math.round((canvasRectangle.height / 2))); + + if(bounds) + { + bounds.x += -(renderingCanvas.screenOffsetX); + bounds.y += -(renderingCanvas.screenOffsetY); + + if(((bounds.width > 1) && (bounds.height > 1))) + { + _local_29 = (((bounds.left - _local_33.x) - (roomGeometry.scale * 0.25)) / _local_24); + _local_31 = (((bounds.right - _local_33.x) + (roomGeometry.scale * 0.25)) / _local_24); + _local_30 = (((bounds.top - _local_33.y) - (roomGeometry.scale * 0.5)) / _local_25); + _local_32 = (((bounds.bottom - _local_33.y) + (roomGeometry.scale * 0.5)) / _local_25); + } + else + { + roomGeometry.adjustLocation(new Vector3d(-30, -30), 25); + + return; + } + } + else + { + roomGeometry.adjustLocation(new Vector3d(0, 0), 25); + + return; + } + + let _local_34 = false; + let _local_35 = false; + let _local_36 = false; + let _local_37 = false; + const _local_38 = Math.round(((_local_31 - _local_29) * _local_24)); + + if(_local_38 < canvasRectangle.width) + { + _local_10 = 2; + _local_23.x = ((_local_31 + _local_29) / 2); + _local_36 = true; + } + else + { + if(_local_23.x > (_local_31 - _local_27)) + { + _local_23.x = (_local_31 - _local_27); + _local_34 = true; + } + if(_local_23.x < (_local_29 + _local_27)) + { + _local_23.x = (_local_29 + _local_27); + _local_34 = true; + } + } + const _local_39 = Math.round(((_local_32 - _local_30) * _local_25)); + if(_local_39 < canvasRectangle.height) + { + _local_10 = 2; + _local_23.y = ((_local_32 + _local_30) / 2); + _local_37 = true; + } + else + { + if(_local_23.y > (_local_32 - _local_28)) + { + _local_23.y = (_local_32 - _local_28); + _local_35 = true; + } + if(_local_23.y < (_local_30 + _local_28)) + { + _local_23.y = (_local_30 + _local_28); + _local_35 = true; + } + if(_local_35) + { + _local_23.y = (_local_23.y / (_local_25 / _local_24)); + } + } + _local_26.invert(); + _local_23 = _local_26.apply(_local_23); + _local_23.x = (_local_23.x + _local_20); + _local_23.y = (_local_23.y + _local_21); + let _local_40 = 0.35; + let _local_41 = 0.2; + let _local_42 = 0.2; + const _local_43 = 10; + const _local_44 = 10; + if((_local_42 * width) > 100) + { + _local_42 = (100 / width); + } + if((_local_40 * height) > 150) + { + _local_40 = (150 / height); + } + if((_local_41 * height) > 150) + { + _local_41 = (150 / height); + } + if((((roomCamera._Str_10235) && (roomCamera._Str_7609 == width)) && (roomCamera._Str_7902 == height))) + { + _local_42 = 0; + } + if((((roomCamera._Str_10446) && (roomCamera._Str_7609 == width)) && (roomCamera._Str_7902 == height))) + { + _local_40 = 0; + _local_41 = 0; + } + + canvasRectangle.width = (canvasRectangle.width * (1 - (_local_42 * 2))); + canvasRectangle.height = (canvasRectangle.height * (1 - (_local_40 + _local_41))); + + if(canvasRectangle.width < _local_43) + { + canvasRectangle.width = _local_43; + } + + if(canvasRectangle.height < _local_44) + { + canvasRectangle.height = _local_44; + } + + if((_local_40 + _local_41) > 0) + { + canvasRectangle.x += (-(canvasRectangle.width) / 2); + canvasRectangle.y += (-(canvasRectangle.height) * (_local_41 / (_local_40 + _local_41))); + } + else + { + canvasRectangle.x += (-(canvasRectangle.width) / 2); + canvasRectangle.y += (-(canvasRectangle.height) / 2); + } + + _local_33 = roomGeometry.getScreenPoint(_local_15); + + if(!_local_33) return; + + if(_local_33) + { + _local_33.x = (_local_33.x + renderingCanvas.screenOffsetX); + _local_33.y = (_local_33.y + renderingCanvas.screenOffsetY); + _local_15.z = _local_10; + _local_15.x = (Math.round((_local_23.x * 2)) / 2); + _local_15.y = (Math.round((_local_23.y * 2)) / 2); + if(!roomCamera.location) + { + roomGeometry.location = _local_15; + if(this._Str_11555) + { + roomCamera._Str_20685(new Vector3d(0, 0, 0)); + } + else + { + roomCamera._Str_20685(_local_15); + } + } + const _local_45 = roomGeometry.getScreenPoint(_local_15); + const _local_46 = new Vector3d(0, 0, 0); + if(_local_45) + { + _local_46.x = _local_45.x; + _local_46.y = _local_45.y; + } + if(((((((((_local_33.x < canvasRectangle.left) || (_local_33.x > canvasRectangle.right)) && (!(roomCamera._Str_8564))) || (((_local_33.y < canvasRectangle.top) || (_local_33.y > canvasRectangle.bottom)) && (!(roomCamera._Str_8690)))) || (((_local_36) && (!(roomCamera._Str_8564))) && (!(roomCamera._Str_7609 == width)))) || (((_local_37) && (!(roomCamera._Str_8690))) && (!(roomCamera._Str_7902 == height)))) || ((!(roomCamera._Str_18975 == bounds.width)) || (!(roomCamera._Str_15953 == bounds.height)))) || ((!(roomCamera._Str_7609 == width)) || (!(roomCamera._Str_7902 == height))))) + { + roomCamera._Str_10235 = _local_34; + roomCamera._Str_10446 = _local_35; + if(this._Str_11555) + { + roomCamera.target = _local_46; + } + else + { + roomCamera.target = _local_15; + } + } + else + { + if(!_local_34) roomCamera._Str_10235 = false; + + if(!_local_35) roomCamera._Str_10446 = false; + } + } + + roomCamera._Str_8564 = _local_36; + roomCamera._Str_8690 = _local_37; + roomCamera._Str_7609 = width; + roomCamera._Str_7902 = height; + roomCamera.scale = roomGeometry.scale; + roomCamera._Str_16377 = roomGeometry.updateId; + roomCamera._Str_18975 = bounds.width; + roomCamera._Str_15953 = bounds.height; + + if(!this._sessionDataManager.isCameraFollowDisabled) + { + if(this._Str_11555) + { + roomCamera.update(time, 8); + } + else + { + roomCamera.update(time, 0.5); + } + } + + if(this._Str_11555) + { + renderingCanvas.screenOffsetX = -(roomCamera.location.x); + renderingCanvas.screenOffsetY = -(roomCamera.location.y); + } + else + { + roomGeometry.adjustLocation(roomCamera.location, 25); + } + } + else + { + roomCamera._Str_10235 = false; + roomCamera._Str_10446 = false; + roomCamera._Str_8564 = false; + roomCamera._Str_8690 = false; + } + } + + private _Str_25261(roomId: number, canvasId: number): Rectangle + { + const canvas = this.getRoomInstanceRenderingCanvas(roomId, canvasId); + + if(!canvas) return null; + + return new Rectangle(0, 0, canvas.width, canvas.height); + } + + public getRoomObjectBoundingRectangle(roomId: number, objectId: number, category: number, canvasId: number): Rectangle + { + const geometry = this.getRoomInstanceGeometry(roomId, canvasId); + + if(!geometry) return null; + + const roomObject = this.getRoomObject(roomId, objectId, category); + + if(!roomObject) return null; + + const visualization = roomObject.visualization; + + if(!visualization) return null; + + const rectangle = visualization.getBoundingRectangle(); + const canvas = this.getRoomInstanceRenderingCanvas(roomId, canvasId); + const scale = ((canvas) ? canvas.scale : 1); + const screenPoint = geometry.getScreenPoint(roomObject.getLocation()); + + if(!screenPoint) return null; + + rectangle.x = (rectangle.x * scale); + rectangle.y = (rectangle.y * scale); + rectangle.width = (rectangle.width * scale); + rectangle.height = (rectangle.height * scale); + + screenPoint.x = (screenPoint.x * scale); + screenPoint.y = (screenPoint.y * scale); + + rectangle.x += screenPoint.x; + rectangle.y += screenPoint.y; + + if(!canvas) return null; + + rectangle.x += ((canvas.width / 2) + canvas.screenOffsetX); + rectangle.y += ((canvas.height / 2) + canvas.screenOffsetY); + + return rectangle; + } + + public getCanvasBoundingRectangle(canvasId: number): Rectangle + { + return this.getRoomObjectBoundingRectangle(this._activeRoomId, RoomEngine.ROOM_OBJECT_ID, RoomObjectCategory.ROOM, canvasId); + } + + public getFurnitureFloorName(typeId: number): string + { + if(!this._roomContentLoader) return null; + + return this._roomContentLoader.getFurnitureFloorNameForTypeId(typeId); + } + + public getFurnitureWallName(typeId: number, extra: string = null): string + { + if(!this._roomContentLoader) return null; + + return this._roomContentLoader.getFurnitureWallNameForTypeId(typeId, extra); + } + + public getFurnitureFloorColorIndex(typeId: number): number + { + if(!this._roomContentLoader) return null; + + return this._roomContentLoader.getFurnitureFloorColorIndex(typeId); + } + + public getFurnitureWallColorIndex(typeId: number): number + { + if(!this._roomContentLoader) return null; + + return this._roomContentLoader.getFurnitureWallColorIndex(typeId); + } + + private getRoomInstanceData(roomId: number): RoomInstanceData + { + const existing = this._roomInstanceDatas.get(roomId); + + if(existing) return existing; + + const data = new RoomInstanceData(roomId); + + this._roomInstanceDatas.set(data.roomId, data); + + return data; + } + + public getRoomInstanceModelName(roomId: number): string + { + const instanceData = this.getRoomInstanceData(roomId); + + if(!instanceData) return null; + + return instanceData.modelName; + } + + public setRoomInstanceModelName(roomId: number, name: string): void + { + const instanceData = this.getRoomInstanceData(roomId); + + if(!instanceData) return; + + instanceData.setModelName(name); + } + + public getRoomTileObjectMap(k: number): TileObjectMap + { + const roomInstance = this.getRoomInstanceData(k); + + if(!roomInstance) return null; + + return roomInstance.tileObjectMap; + } + + private getCurrentRoomCamera(): RoomCamera + { + return this.getRoomCamera(this._activeRoomId); + } + + private getRoomCamera(roomId: number): RoomCamera + { + const instanceData = this.getRoomInstanceData(roomId); + + if(!instanceData) return null; + + return instanceData.roomCamera; + } + + public getSelectedRoomObjectData(roomId: number): SelectedRoomObjectData + { + const instanceData = this.getRoomInstanceData(roomId); + + if(!instanceData) return null; + + return instanceData.selectedObject; + } + + public setSelectedRoomObjectData(roomId: number, data: SelectedRoomObjectData): void + { + const instanceData = this.getRoomInstanceData(roomId); + + if(!instanceData) return null; + + instanceData.setSelectedObject(data); + + if(data) instanceData.setPlacedObject(null); + } + + public getPlacedRoomObjectData(roomId: number): SelectedRoomObjectData + { + const instanceData = this.getRoomInstanceData(roomId); + + if(!instanceData) return null; + + return instanceData.placedObject; + } + + public setPlacedRoomObjectData(roomId: number, data: SelectedRoomObjectData): void + { + const instanceData = this.getRoomInstanceData(roomId); + + if(!instanceData) return null; + + instanceData.setPlacedObject(data); + } + + public cancelRoomObjectPlacement(): void + { + if(!this._roomObjectEventHandler) return; + + this._roomObjectEventHandler.cancelRoomObjectPlacement(this._activeRoomId); + } + + public getFurnitureStackingHeightMap(roomId: number): FurnitureStackingHeightMap + { + const instanceData = this.getRoomInstanceData(roomId); + + if(!instanceData) return null; + + return instanceData.furnitureStackingHeightMap; + } + + public setFurnitureStackingHeightMap(roomId: number, heightMap: FurnitureStackingHeightMap): void + { + const instanceData = this.getRoomInstanceData(roomId); + + if(!instanceData) return null; + + instanceData.setFurnitureStackingHeightMap(heightMap); + } + + public getLegacyWallGeometry(roomId: number): LegacyWallGeometry + { + const instanceData = this.getRoomInstanceData(roomId); + + if(!instanceData) return null; + + return instanceData.legacyGeometry; + } + + private createRoomObjectAndInitialize(roomId: number, objectId: number, type: string, category: number): IRoomObjectController + { + const instance = this.getRoomInstance(roomId); + + if(!instance) return null; + + return instance.createRoomObjectAndInitalize(objectId, type, category) as IRoomObjectController; + } + + public getTotalObjectsForManager(roomId: number, category: number): number + { + const instance = this.getRoomInstance(roomId); + + if(!instance) return 0; + + return instance.getTotalObjectsForManager(category); + } + + public getRoomObject(roomId: number, objectId: number, category: number): IRoomObjectController + { + if(!this._ready) return null; + + let roomIdString = this.getRoomId(roomId); + + if(roomId === 0) roomIdString = RoomEngine.TEMPORARY_ROOM; + + return this.getObject(roomIdString, objectId, category); + } + + public getObject(roomId: string, objectId: number, category: number): IRoomObjectController + { + let roomInstance: IRoomInstance = null; + + if(this._roomManager) roomInstance = this._roomManager.getRoomInstance(roomId); + + if(!roomInstance) return null; + + let roomObject = (roomInstance.getRoomObject(objectId, category) as IRoomObjectController); + + if(!roomObject) + { + switch(category) + { + case RoomObjectCategory.FLOOR: + this.processPendingFurnitureFloor(this.getRoomIdFromString(roomId), objectId, null); + + roomObject = (roomInstance.getRoomObject(objectId, category) as IRoomObjectController); + break; + case RoomObjectCategory.WALL: + this.processPendingFurnitureWall(this.getRoomIdFromString(roomId), objectId, null); + + roomObject = (roomInstance.getRoomObject(objectId, category) as IRoomObjectController); + break; + } + } + + return roomObject; + } + + public getRoomObjectByIndex(roomId: number, index: number, category: number): IRoomObjectController + { + const instance = this.getRoomInstance(roomId); + + if(!instance) return null; + + return instance.getRoomObjectByIndex(index, category) as IRoomObjectController; + } + + public getRoomObjectCategoryForType(type: string): number + { + if(!type || !this._roomContentLoader) return RoomObjectCategory.MINIMUM; + + return this._roomContentLoader.getCategoryForType(type); + } + + public getRoomObjectCursor(roomId: number): IRoomObjectController + { + return this.getObject(this.getRoomId(roomId), RoomEngine.CURSOR_OBJECT_ID, RoomObjectCategory.CURSOR); + } + + public getRoomObjectSelectionArrow(roomId: number): IRoomObjectController + { + return this.getObject(this.getRoomId(roomId), RoomEngine.ARROW_OBJECT_ID, RoomObjectCategory.CURSOR); + } + + public getRoomOwnObject(roomId: number): IRoomObjectController + { + return this.getObject(this.getRoomId(roomId), RoomEngine.ROOM_OBJECT_ID, RoomObjectCategory.ROOM); + } + + public getRoomObjectUser(roomId: number, objectId: number): IRoomObjectController + { + return this.getObject(this.getRoomId(roomId), objectId, RoomObjectCategory.UNIT); + } + + public removeRoomObjectUser(roomId: number, objectId: number): void + { + return this.removeRoomObject(roomId, objectId, RoomObjectCategory.UNIT); + } + + public createRoomObjectUser(roomId: number, objectId: number, type: string): IRoomObjectController + { + return this.createRoomObjectAndInitialize(roomId, objectId, type, RoomObjectCategory.UNIT); + } + + public getRoomObjectFloor(roomId: number, objectId: number): IRoomObjectController + { + return this.getObject(this.getRoomId(roomId), objectId, RoomObjectCategory.FLOOR); + } + + public createRoomObjectFloor(roomId: number, id: number, type: string): IRoomObjectController + { + return this.createRoomObjectAndInitialize(roomId, id, type, RoomObjectCategory.FLOOR); + } + + public removeRoomObjectFloor(roomId: number, objectId: number, userId: number = -1, _arg_4: boolean = false): void + { + const roomInstanceData = this.getRoomInstanceData(roomId); + + if(roomInstanceData) roomInstanceData.removePendingFunitureFloor(objectId); + + if(this._sessionDataManager && (userId === this._sessionDataManager.userId) && !FurniId.isBuilderClubId(objectId)) + { + const roomObject = this.getRoomObject(roomId, objectId, RoomObjectCategory.FLOOR); + + if(roomObject) + { + const screenLocation = this.getRoomObjectScreenLocation(roomId, objectId, RoomObjectCategory.FLOOR, this._activeRoomActiveCanvas); + + if(screenLocation) + { + const disabledPickingAnimation = (roomObject.model.getValue(RoomObjectVariable.FURNITURE_DISABLE_PICKING_ANIMATION) === 1); + + if(!disabledPickingAnimation) + { + const typeId = roomObject.model.getValue(RoomObjectVariable.FURNITURE_TYPE_ID); + const extras = roomObject.model.getValue(RoomObjectVariable.FURNITURE_EXTRAS); + const dataKey = roomObject.model.getValue(RoomObjectVariable.FURNITURE_DATA_FORMAT); + const objectData = ObjectDataFactory.getData(dataKey); + const icon = this.getFurnitureFloorIcon(typeId, null, extras, objectData).data; + + if(icon) + { + const image = Nitro.instance.renderer.extract.image(icon); + + if(this.events) + { + const event = new NitroToolbarAnimateIconEvent(image, screenLocation.x, screenLocation.y); + + event.iconName = ToolbarIconEnum.INVENTORY; + + this.events.dispatchEvent(event); + } + } + } + } + } + } + + this.removeRoomObject(roomId, objectId, RoomObjectCategory.FLOOR); + this.setMouseDefault(roomId, RoomObjectCategory.FLOOR, objectId); + + if(_arg_4) this._Str_17722(roomId, 'RoomEngine.disposeObjectFurniture()'); + } + + public getRoomObjectWall(roomId: number, objectId: number): IRoomObjectController + { + return this.getObject(this.getRoomId(roomId), objectId, RoomObjectCategory.WALL); + } + + public removeRoomObjectWall(roomId: number, objectId: number, userId: number = -1): void + { + if(this._sessionDataManager && (userId === this._sessionDataManager.userId) && !FurniId.isBuilderClubId(objectId)) + { + const roomObject = this.getRoomObject(roomId, objectId, RoomObjectCategory.WALL); + + if(roomObject && (roomObject.type.indexOf('post_it') === -1) && (roomObject.type.indexOf('external_image_wallitem') === -1)) + { + const screenLocation = this.getRoomObjectScreenLocation(roomId, objectId, RoomObjectCategory.WALL, this._activeRoomActiveCanvas); + + if(screenLocation) + { + const typeId = roomObject.model.getValue(RoomObjectVariable.FURNITURE_TYPE_ID); + const objectData = roomObject.model.getValue(RoomObjectVariable.FURNITURE_DATA); + const icon = this.getFurnitureWallIcon(typeId, null, objectData).data; + + if(icon) + { + const image = Nitro.instance.renderer.extract.image(icon); + + if(this.events) + { + const event = new NitroToolbarAnimateIconEvent(image, screenLocation.x, screenLocation.y); + + event.iconName = ToolbarIconEnum.INVENTORY; + + this.events.dispatchEvent(event); + } + } + } + } + } + + this.removeRoomObject(roomId, objectId, RoomObjectCategory.WALL); + this.updateRoomObjectMask(roomId, objectId, false); + this.setMouseDefault(roomId, RoomObjectCategory.WALL, objectId); + } + + public createRoomObjectWall(roomId: number, id: number, type: string): IRoomObjectController + { + return this.createRoomObjectAndInitialize(roomId, id, type, RoomObjectCategory.WALL); + } + + private removeRoomObject(roomId: number, objectId: number, category: number): void + { + const instance = this.getRoomInstance(roomId); + + if(!instance) return null; + + instance.removeRoomObject(objectId, category); + + if(this.events) this.events.dispatchEvent(new RoomEngineObjectEvent(RoomEngineObjectEvent.REMOVED, roomId, objectId, category)); + } + + public addFurnitureFloor(roomId: number, id: number, typeId: number, location: IVector3D, direction: IVector3D, state: number, objectData: IObjectData, extra: number = NaN, expires: number = -1, usagePolicy: number = 0, ownerId: number = 0, ownerName: string = '', synchronized: boolean = true, realRoomObject: boolean = true, sizeZ: number = -1): boolean + { + const instanceData = this.getRoomInstanceData(roomId); + + if(!instanceData) return false; + + const furnitureData = new FurnitureData(id, typeId, null, location, direction, state, objectData, extra, expires, usagePolicy, ownerId, ownerName, synchronized, realRoomObject, sizeZ); + + instanceData.addPendingFurnitureFloor(furnitureData); + + return true; + } + + public addFurnitureFloorByTypeName(roomId: number, id: number, typeName: string, location: IVector3D, direction: IVector3D, state: number, objectData: IObjectData, extra: number = NaN, expires: number = -1, usagePolicy: number = 0, ownerId: number = 0, ownerName: string = '', synchronized: boolean = true, realRoomObject: boolean = true, sizeZ: number = -1): boolean + { + const instanceData = this.getRoomInstanceData(roomId); + + if(!instanceData) return false; + + const furnitureData = new FurnitureData(id, 0, typeName, location, direction, state, objectData, extra, expires, usagePolicy, ownerId, ownerName, synchronized, realRoomObject, sizeZ); + + instanceData.addPendingFurnitureFloor(furnitureData); + + return true; + } + + public addFurnitureWall(roomId: number, id: number, typeId: number, location: IVector3D, direction: IVector3D, state: number, extra: string, expires: number = -1, usagePolicy: number = 0, ownerId: number = 0, ownerName: string = '', realRoomObject: boolean = true): boolean + { + const instanceData = this.getRoomInstanceData(roomId); + + if(!instanceData) return false; + + const objectData = new LegacyDataType(); + + objectData.setString(extra); + + const furnitureData = new FurnitureData(id, typeId, null, location, direction, state, objectData, NaN, expires, usagePolicy, ownerId, ownerName, true, realRoomObject); + + instanceData.addPendingFurnitureWall(furnitureData); + + return true; + } + + public updateRoomObjectFloor(roomId: number, objectId: number, location: IVector3D, direction: IVector3D, state: number, data: IObjectData, extra: number = NaN): boolean + { + const object = this.getRoomObjectFloor(roomId, objectId); + + if(!object) return false; + + object.processUpdateMessage(new RoomObjectUpdateMessage(location, direction)); + object.processUpdateMessage(new ObjectDataUpdateMessage(state, data, extra)); + + return true; + } + + public updateRoomObjectWall(roomId: number, objectId: number, location: IVector3D, direction: IVector3D, state: number, extra: string = null): boolean + { + const object = this.getRoomObjectWall(roomId, objectId); + + if(!object || !object.logic) return false; + + const updateMessage = new RoomObjectUpdateMessage(location, direction); + const data = new LegacyDataType(); + const dataUpdateMessage = new ObjectDataUpdateMessage(state, data); + + data.setString(extra); + + object.logic.processUpdateMessage(updateMessage); + object.logic.processUpdateMessage(dataUpdateMessage); + + this.updateRoomObjectMask(roomId, objectId); + + return true; + } + + public updateRoomObjectWallItemData(roomId: number, objectId: number, data: string): boolean + { + const object = this.getRoomObjectWall(roomId, objectId); + + if(!object || !object.logic) return false; + + object.logic.processUpdateMessage(new ObjectItemDataUpdateMessage(data)); + + return true; + } + + public updateRoomObjectFloorHeight(roomId: number, objectId: number, height: number): boolean + { + const object = this.getRoomObjectFloor(roomId, objectId); + + if(!object) return false; + + object.processUpdateMessage(new ObjectHeightUpdateMessage(null, null, height)); + + return true; + } + + public updateRoomObjectFloorExpiration(roomId: number, objectId: number, expires: number): boolean + { + const object = this.getRoomObjectFloor(roomId, objectId); + + if(!object) return false; + + object.model.setValue(RoomObjectVariable.FURNITURE_EXPIRY_TIME, expires); + object.model.setValue(RoomObjectVariable.FURNITURE_EXPIRTY_TIMESTAMP, Nitro.instance.time); + + return true; + } + + public updateRoomObjectWallExpiration(roomId: number, objectId: number, expires: number): boolean + { + const object = this.getRoomObjectWall(roomId, objectId); + + if(!object) return false; + + object.model.setValue(RoomObjectVariable.FURNITURE_EXPIRY_TIME, expires); + object.model.setValue(RoomObjectVariable.FURNITURE_EXPIRTY_TIMESTAMP, Nitro.instance.time); + + return true; + } + + public updateRoomObjectMask(roomId: number, objectId: number, _arg_3: boolean = true): void + { + const maskName = RoomObjectCategory.WALL + '_' + objectId; + const roomObject = this.getRoomObjectWall(roomId, objectId); + + let maskUpdate: ObjectRoomMaskUpdateMessage = null; + + if(roomObject && roomObject.model) + { + if(roomObject.model.getValue(RoomObjectVariable.FURNITURE_USES_PLANE_MASK) > 0) + { + const maskType = roomObject.model.getValue(RoomObjectVariable.FURNITURE_PLANE_MASK_TYPE); + const location = roomObject.getLocation(); + + if(_arg_3) maskUpdate = new ObjectRoomMaskUpdateMessage(ObjectRoomMaskUpdateMessage.ADD_MASK, maskName, maskType, location); + else maskUpdate = new ObjectRoomMaskUpdateMessage(ObjectRoomMaskUpdateMessage._Str_10260, maskName); + } + } + else + { + maskUpdate = new ObjectRoomMaskUpdateMessage(ObjectRoomMaskUpdateMessage._Str_10260, maskName); + } + + const roomOwnObject = this.getRoomOwnObject(roomId); + + if(roomOwnObject && roomOwnObject.logic && maskUpdate) roomOwnObject.logic.processUpdateMessage(maskUpdate); + } + + public rollRoomObjectFloor(roomId: number, objectId: number, location: IVector3D, targetLocation: IVector3D): void + { + const object = this.getRoomObjectFloor(roomId, objectId); + + if(!object) return; + + object.processUpdateMessage(new ObjectMoveUpdateMessage(location, targetLocation, null, !!targetLocation)); + } + + public updateRoomObjectWallLocation(roomId: number, objectId: number, location: IVector3D): boolean + { + const roomObject = this.getRoomObjectWall(roomId, objectId); + + if(!roomObject) return false; + + if(roomObject.logic) roomObject.logic.processUpdateMessage(new ObjectMoveUpdateMessage(location, null, null)); + + this.updateRoomObjectMask(roomId, objectId); + + return true; + } + + public addRoomObjectUser(roomId: number, objectId: number, location: IVector3D, direction: IVector3D, headDirection: number, type: number, figure: string): boolean + { + const existing = this.getRoomObjectUser(roomId, objectId); + + if(existing) return false; + + let objectType = RoomObjectUserType.getTypeString(type); + + if(objectType === RoomObjectUserType.PET) objectType = this.getPetType(figure); + + const object = this.createRoomObjectUser(roomId, objectId, objectType); + + if(!object) return false; + + //object.model.setValue(RoomObjectVariable.FIGURE_HIGHLIGHT_ENABLE, 1); + + object.processUpdateMessage(new ObjectAvatarUpdateMessage(this.fixedUserLocation(roomId, location), null, direction, headDirection, false, 0)); + + if(figure) object.processUpdateMessage(new ObjectAvatarFigureUpdateMessage(figure)); + + if(this.events) this.events.dispatchEvent(new RoomEngineObjectEvent(RoomEngineObjectEvent.ADDED, roomId, objectId, RoomObjectCategory.UNIT)); + + return true; + } + + public updateRoomObjectUserLocation(roomId: number, objectId: number, location: IVector3D, targetLocation: IVector3D, canStandUp: boolean = false, baseY: number = 0, direction: IVector3D = null, headDirection: number = NaN): boolean + { + const object = this.getRoomObjectUser(roomId, objectId); + + if(!object) return false; + + if(!location) location = object.getLocation(); + + if(!direction) direction = object.getDirection(); + + if(isNaN(headDirection)) headDirection = object.model.getValue(RoomObjectVariable.HEAD_DIRECTION); + + object.processUpdateMessage(new ObjectAvatarUpdateMessage(this.fixedUserLocation(roomId, location), this.fixedUserLocation(roomId, targetLocation), direction, headDirection, canStandUp, baseY)); + + const roomSession = ((this._roomSessionManager && this._roomSessionManager.getSession(roomId)) || null); + + if(roomSession && (roomSession.ownRoomIndex === objectId)) + { + this._logicFactory.events.dispatchEvent(new RoomToObjectOwnAvatarMoveEvent(RoomToObjectOwnAvatarMoveEvent.ROAME_MOVE_TO, targetLocation)); + } + + return true; + } + + private fixedUserLocation(roomId: number, location: IVector3D): IVector3D + { + if(!location) return null; + + const heightMap = this.getFurnitureStackingHeightMap(roomId); + const wallGeometry = this.getLegacyWallGeometry(roomId); + + if(!heightMap || !wallGeometry) return location; + + let _local_5 = location.z; + const _local_6 = heightMap.getTileHeight(location.x, location.y); + const _local_7 = wallGeometry.getHeight(location.x, location.y); + + if((Math.abs((_local_5 - _local_6)) < 0.1) && (Math.abs((_local_6 - _local_7)) < 0.1)) + { + _local_5 = wallGeometry._Str_24141(location.x, location.y); + } + + return new Vector3d(location.x, location.y, _local_5); + } + + public updateRoomObjectUserAction(roomId: number, objectId: number, action: string, value: number, parameter: string = null): boolean + { + const object = this.getRoomObjectUser(roomId, objectId); + + if(!object) return false; + + let message: ObjectStateUpdateMessage = null; + + switch(action) + { + case RoomObjectVariable.FIGURE_TALK: + message = new ObjectAvatarChatUpdateMessage(value); + break; + case RoomObjectVariable.FIGURE_SLEEP: + message = new ObjectAvatarSleepUpdateMessage(value === 1); + break; + case RoomObjectVariable.FIGURE_IS_TYPING: + message = new ObjectAvatarTypingUpdateMessage(value === 1); + break; + case RoomObjectVariable.FIGURE_IS_MUTED: + message = new ObjectAvatarMutedUpdateMessage(value === 1); + break; + case RoomObjectVariable.FIGURE_CARRY_OBJECT: + message = new ObjectAvatarCarryObjectUpdateMessage(value, parameter); + break; + case RoomObjectVariable.FIGURE_USE_OBJECT: + message = new ObjectAvatarUseObjectUpdateMessage(value); + break; + case RoomObjectVariable.FIGURE_DANCE: + message = new ObjectAvatarDanceUpdateMessage(value); + break; + case RoomObjectVariable.FIGURE_GAINED_EXPERIENCE: + message = new ObjectAvatarExperienceUpdateMessage(value); + break; + case RoomObjectVariable.FIGURE_NUMBER_VALUE: + message = new ObjectAvatarPlayerValueUpdateMessage(value); + break; + case RoomObjectVariable.FIGURE_SIGN: + message = new ObjectAvatarSignUpdateMessage(value); + break; + case RoomObjectVariable.FIGURE_EXPRESSION: + message = new ObjectAvatarExpressionUpdateMessage(value); + break; + case RoomObjectVariable.FIGURE_IS_PLAYING_GAME: + message = new ObjectAvatarPlayingGameUpdateMessage(value === 1); + break; + case RoomObjectVariable.FIGURE_GUIDE_STATUS: + message = new ObjectAvatarGuideStatusUpdateMessage(value); + break; + } + + if(!message) return false; + + object.processUpdateMessage(message); + + return true; + } + + public updateRoomObjectUserFigure(roomId: number, objectId: number, figure: string, gender: string = null, subType: string = null, isRiding: boolean = false): boolean + { + const object = this.getRoomObjectUser(roomId, objectId); + + if(!object) return false; + + object.processUpdateMessage(new ObjectAvatarFigureUpdateMessage(figure, gender, subType, isRiding)); + + return true; + } + + public updateRoomObjectUserFlatControl(roomId: number, objectId: number, level: string): boolean + { + const object = this.getRoomObjectUser(roomId, objectId); + + if(!object) return false; + + object.processUpdateMessage(new ObjectAvatarFlatControlUpdateMessage(parseInt(level))); + + return true; + } + + public updateRoomObjectUserEffect(roomId: number, objectId: number, effectId: number, delay: number = 0): boolean + { + const object = this.getRoomObjectUser(roomId, objectId); + + if(!object) return false; + + object.processUpdateMessage(new ObjectAvatarEffectUpdateMessage(effectId, delay)); + + return true; + } + + public updateRoomObjectUserGesture(roomId: number, objectId: number, gestureId: number): boolean + { + const object = this.getRoomObjectUser(roomId, objectId); + + if(!object) return false; + + object.processUpdateMessage(new ObjectAvatarGestureUpdateMessage(gestureId)); + + return true; + } + + public updateRoomObjectUserPetGesture(roomId: number, objectId: number, gesture: string): boolean + { + const object = this.getRoomObjectUser(roomId, objectId); + + if(!object) return false; + + object.processUpdateMessage(new ObjectAvatarPetGestureUpdateMessage(gesture)); + + return true; + } + + public updateRoomObjectUserPosture(roomId: number, objectId: number, type: string, parameter: string = null): boolean + { + const object = this.getRoomObjectUser(roomId, objectId); + + if(!object) return false; + + object.processUpdateMessage(new ObjectAvatarPostureUpdateMessage(type, parameter)); + + return true; + } + + public updateRoomObjectUserOwn(roomId: number, objectId: number): void + { + const object = this.getRoomObjectUser(roomId, objectId); + + if(!object) return; + + object.processUpdateMessage(new ObjectAvatarOwnMessage()); + } + + public useRoomObject(objectId: number, category: number): boolean + { + const roomObject = this.getRoomObject(this._activeRoomId, objectId, category); + + if(roomObject) + { + const eventHandler = roomObject.logic; + + if(eventHandler) + { + eventHandler.useObject(); + + return true; + } + } + + return false; + } + + public objectInitialized(roomId: string, objectId: number, category: number): void + { + const id = this.getRoomIdFromString(roomId); + + if(category === RoomObjectCategory.WALL) + { + this.updateRoomObjectMask(id, objectId); + } + + const object = this.getRoomObject(id, objectId, category); + + if(object && object.model && object.logic) + { + const dataFormat = object.model.getValue(RoomObjectVariable.FURNITURE_DATA_FORMAT); + + if(!isNaN(dataFormat)) + { + const data = ObjectDataFactory.getData(dataFormat); + + data.initializeFromRoomObjectModel(object.model); + + object.processUpdateMessage(new ObjectDataUpdateMessage(object.getState(0), data)); + } + + this.events.dispatchEvent(new RoomEngineObjectEvent(RoomEngineObjectEvent.CONTENT_UPDATED, id, objectId, category)); + } + + if(roomId !== RoomEngine.TEMPORARY_ROOM) this._Str_21543(id, object); + } + + public changeObjectModelData(roomId: number, objectId: number, category: number, numberKey: string, numberValue: number): boolean + { + const roomObject = this.getObject(this.getRoomId(roomId), objectId, category); + + if(!roomObject || !roomObject.logic) return false; + + const message = new ObjectModelDataUpdateMessage(numberKey, numberValue); + + roomObject.processUpdateMessage(message); + + return true; + } + + public changeObjectState(roomId: number, objectId: number, category: number): void + { + const roomObject = this.getObject(this.getRoomId(roomId), objectId, category); + + if(!roomObject || !roomObject.model) return; + + let stateIndex = roomObject.model.getValue(RoomObjectVariable.FURNITURE_AUTOMATIC_STATE_INDEX); + + if(isNaN(stateIndex)) stateIndex = 1; + else stateIndex = (stateIndex + 1); + + roomObject.model.setValue(RoomObjectVariable.FURNITURE_AUTOMATIC_STATE_INDEX, stateIndex); + + const objectDataKey = roomObject.model.getValue(RoomObjectVariable.FURNITURE_DATA_FORMAT); + const objectData = ObjectDataFactory.getData(objectDataKey); + + objectData.initializeFromRoomObjectModel(roomObject.model); + + if(roomObject.logic) roomObject.logic.processUpdateMessage(new ObjectDataUpdateMessage(stateIndex, objectData)); + } + + public loadRoomObjectBadgeImage(roomId: number, objectId: number, objectCategory: number, badgeId: string, groupBadge: boolean = true): void + { + if(!this._sessionDataManager) return; + + const roomObject = this.getRoomObjectFloor(roomId, objectId); + + if(!roomObject || !roomObject.logic) return; + + let badgeName = (groupBadge) ? this._sessionDataManager.loadGroupBadgeImage(badgeId) : this._sessionDataManager.loadBadgeImage(badgeId); + + if(!badgeName) + { + badgeName = 'loading_icon'; + + if(!this._badgeListenerObjects) this._badgeListenerObjects = new Map(); + + if(!this._badgeListenerObjects.size) + { + this._sessionDataManager.events.addEventListener(BadgeImageReadyEvent.IMAGE_READY, this.onBadgeImageReadyEvent); + } + + let listeners = this._badgeListenerObjects.get(badgeId); + + if(!listeners) listeners = []; + + listeners.push(new RoomObjectBadgeImageAssetListener(roomObject, groupBadge)); + + this._badgeListenerObjects.set(badgeId, listeners); + } + else + { + this.putBadgeInObjectAssets(roomObject, badgeId, groupBadge); + } + + roomObject.logic.processUpdateMessage(new ObjectGroupBadgeUpdateMessage(badgeId, badgeName)); + } + + private onBadgeImageReadyEvent(k: BadgeImageReadyEvent): void + { + if(!this._sessionDataManager) return; + + const listeners = this._badgeListenerObjects && this._badgeListenerObjects.get(k.badgeId); + + if(!listeners) return; + + for(const listener of listeners) + { + if(!listener) continue; + + this.putBadgeInObjectAssets(listener.object, k.badgeId, listener.groupBadge); + + const badgeName = (listener.groupBadge) ? this._sessionDataManager.loadGroupBadgeImage(k.badgeId) : this._sessionDataManager.loadBadgeImage(k.badgeId); + + if(listener.object && listener.object.logic) listener.object.logic.processUpdateMessage(new ObjectGroupBadgeUpdateMessage(k.badgeId, badgeName)); + } + + this._badgeListenerObjects.delete(k.badgeId); + + if(!this._badgeListenerObjects.size) + { + this._sessionDataManager.events.removeEventListener(BadgeImageReadyEvent.IMAGE_READY, this.onBadgeImageReadyEvent); + } + } + + private putBadgeInObjectAssets(object: IRoomObjectController, badgeId: string, groupBadge: boolean = false): void + { + if(!this._roomContentLoader || !this._sessionDataManager) return; + + const badgeName = (groupBadge) ? this._sessionDataManager.loadGroupBadgeImage(badgeId) : this._sessionDataManager.loadBadgeImage(badgeId); + const badgeImage = (groupBadge) ? this._sessionDataManager.getGroupBadgeImage(badgeId) : this._sessionDataManager.getBadgeImage(badgeId); + + if(badgeImage) this._roomContentLoader.addAssetToCollection(object.type, badgeName, badgeImage); + } + + public dispatchMouseEvent(canvasId: number, x: number, y: number, type: string, altKey: boolean, ctrlKey: boolean, shiftKey: boolean, buttonDown: boolean): void + { + const canvas = this.getRoomInstanceRenderingCanvas(this._activeRoomId, canvasId); + + if(!canvas) return; + + const overlay = this.getRenderingCanvasOverlay(canvas); + const sprite = this._Str_16498(overlay, RoomEngine.OBJECT_ICON_SPRITE); + + if(sprite) + { + const rectangle = sprite.getLocalBounds(); + + sprite.x = (x - (rectangle.width / 2)); + sprite.y = (y - (rectangle.height / 2)); + } + + if(!this._Str_25871(canvas, x, y, type, altKey, ctrlKey, shiftKey)) + { + if(!canvas._Str_21232(x, y, type, altKey, ctrlKey, shiftKey, buttonDown)) + { + let eventType: string = null; + + if(type === MouseEventType.MOUSE_CLICK) + { + if(this.events) + { + this.events.dispatchEvent(new RoomEngineObjectEvent(RoomEngineObjectEvent.DESELECTED, this._activeRoomId, -1, RoomObjectCategory.MINIMUM)); + } + + eventType = RoomObjectMouseEvent.CLICK; + } + else + { + if(type === MouseEventType.MOUSE_MOVE) eventType = RoomObjectMouseEvent.MOUSE_MOVE; + + else if(type === MouseEventType.MOUSE_DOWN) eventType = RoomObjectMouseEvent.MOUSE_DOWN; + + else if(type === MouseEventType.MOUSE_UP) eventType = RoomObjectMouseEvent.MOUSE_UP; + } + + this._roomObjectEventHandler.handleRoomObjectEvent(new RoomObjectMouseEvent(eventType, this.getRoomObject(this._activeRoomId, RoomEngine.ROOM_OBJECT_ID, RoomObjectCategory.ROOM), null, altKey), this._activeRoomId); + } + } + + this._activeRoomActiveCanvas = canvasId; + this._activeRoomActiveCanvasMouseX = x; + this._activeRoomActiveCanvasMouseY = y; + } + + private _Str_25871(canvas: IRoomRenderingCanvas, x: number, y: number, type: string, altKey: boolean, ctrlKey: boolean, shiftKey: boolean): boolean + { + let offsetX = (x - this._activeRoomActiveCanvasMouseX); + let offsetY = (y - this._activeRoomActiveCanvasMouseY); + + if(type === MouseEventType.MOUSE_DOWN) + { + if(!altKey && !ctrlKey && !shiftKey && !this.isDecorating) + { + if(this._roomAllowsDragging) + { + this._activeRoomIsDragged = true; + this._activeRoomWasDragged = false; + this._activeRoomDragStartX = this._activeRoomActiveCanvasMouseX; + this._activeRoomDragStartY = this._activeRoomActiveCanvasMouseY; + } + } + } + else + { + if(type === MouseEventType.MOUSE_UP) + { + if(this._activeRoomIsDragged) + { + this._activeRoomIsDragged = false; + + if(this._activeRoomWasDragged) + { + const instanceData = this.getRoomInstanceData(this._activeRoomId); + + if(instanceData) + { + const camera = instanceData.roomCamera; + + if(camera) + { + if(this._Str_11555) + { + if(!camera._Str_12536) + { + camera._Str_8564 = false; + camera._Str_8690 = false; + } + + camera._Str_25467(new Vector3d(-(canvas.screenOffsetX), -(canvas.screenOffsetY))); + } + + if(this._roomDraggingAlwaysCenters) camera.reset(); + } + } + } + } + } + else + { + if(type === MouseEventType.MOUSE_MOVE) + { + if(this._activeRoomIsDragged) + { + if(!this._activeRoomWasDragged) + { + offsetX = (x - this._activeRoomDragStartX); + offsetY = (y - this._activeRoomDragStartY); + + if(((((offsetX <= -(RoomEngine.DRAG_THRESHOLD)) || (offsetX >= RoomEngine.DRAG_THRESHOLD)) || (offsetY <= -(RoomEngine.DRAG_THRESHOLD))) || (offsetY >= RoomEngine.DRAG_THRESHOLD))) + { + this._activeRoomWasDragged = true; + } + + offsetX = 0; + offsetY = 0; + } + + if(((!(offsetX == 0)) || (!(offsetY == 0)))) + { + this._activeRoomDragX += offsetX; + this._activeRoomDragY += offsetY; + + this._activeRoomWasDragged = true; + } + } + } + else + { + if((type === MouseEventType.MOUSE_CLICK) || (type === MouseEventType.DOUBLE_CLICK)) + { + this._activeRoomIsDragged = false; + + if(this._activeRoomWasDragged) + { + this._activeRoomWasDragged = false; + + return true; + } + } + } + } + } + + return false; + } + + public updateMousePointer(type: string, objectId: number, objectType: string): void + { + const category = this.getRoomObjectCategoryForType(objectType); + + switch(type) + { + case RoomObjectFurnitureActionEvent.MOUSE_BUTTON: + this.setMouseButton(this._activeRoomId, category, objectId); + return; + default: + this.setMouseDefault(this._activeRoomId, category, objectId); + return; + } + } + + private setMouseButton(roomId: number, category: number, objectId: number): void + { + if(!this._roomSessionManager) return; + + const session = this._roomSessionManager.getSession(roomId); + + if(!session) return; + + if(((category !== RoomObjectCategory.FLOOR) && (category !== RoomObjectCategory.WALL)) || ((session.controllerLevel >= RoomControllerLevel.GUEST))) + { + const instanceData = this.getRoomInstanceData(roomId); + + if(instanceData) + { + if(instanceData._Str_16810((category + '_' + objectId))) this._mouseCursorUpdate = true; + } + } + } + + private setMouseDefault(roomId: number, category: number, objectId: number): void + { + if(!this._roomSessionManager) return; + + const instanceData = this.getRoomInstanceData(roomId); + + if(instanceData) + { + if(instanceData._Str_11959((category + '_' + objectId))) this._mouseCursorUpdate = true; + } + } + + public processRoomObjectOperation(objectId: number, category: number, operation: string): boolean + { + if(!this._roomObjectEventHandler) return false; + + this._roomObjectEventHandler.processRoomObjectOperation(this._activeRoomId, objectId, category, operation); + } + + public processRoomObjectWallOperation(objectId: number, category: number, operation: string, data: Map): boolean + { + if(!this._roomObjectEventHandler) return false; + + if(category !== RoomObjectCategory.WALL) return; + + this._roomObjectEventHandler.processRoomObjectWallOperation(this._activeRoomId, objectId, category, operation, data); + } + + public processRoomObjectFloorOperation(objectId: number, category: number, operation: string, data: string): boolean + { + if(!this._roomObjectEventHandler) return false; + + if(category !== RoomObjectCategory.FLOOR) return; + + this._roomObjectEventHandler.processRoomObjectFloorOperation(this._activeRoomId, objectId, operation, data); + } + + private processRoomObjectEvent(event: RoomObjectEvent): void + { + if(!this._roomObjectEventHandler) return; + + const roomIdString = this.getRoomObjectRoomId(event.object); + + if(!roomIdString) return; + + const roomId = this.getRoomIdFromString(roomIdString); + + this._roomObjectEventHandler.handleRoomObjectEvent(event, roomId); + } + + public processRoomObjectPlacement(placementSource: string, id: number, category: number, typeId: number, extra: string = null, stuffData: IObjectData = null, state: number = -1, frameNumber: number = -1, posture: string = null): boolean + { + const roomInstance = this.getRoomInstance(this._activeRoomId); + + if(!roomInstance || (roomInstance.model.getValue(RoomVariableEnum.ROOM_IS_PUBLIC) !== 0)) return false; + + if(!this._roomObjectEventHandler) return false; + + return this._roomObjectEventHandler.processRoomObjectPlacement(placementSource, this._activeRoomId, id, category, typeId, extra, stuffData, state, frameNumber, posture); + } + + public getRoomObjectScreenLocation(roomId: number, objectId: number, objectType: number, canvasId: number = -1): Point + { + if(canvasId == -1) canvasId = this._activeRoomActiveCanvas; + + const geometry = this.getRoomInstanceGeometry(roomId, canvasId); + + if(!geometry) return null; + + const roomObject = this.getRoomObject(roomId, objectId, objectType); + + if(!roomObject) return null; + + const screenPoint = geometry.getScreenPoint(roomObject.getLocation()); + + if(!screenPoint) return null; + + const renderingCanvas = this.getRoomInstanceRenderingCanvas(roomId, canvasId); + + if(!renderingCanvas) return null; + + screenPoint.x = (screenPoint.x * renderingCanvas.scale); + screenPoint.y = (screenPoint.y * renderingCanvas.scale); + + screenPoint.x += ((renderingCanvas.width / 2) + renderingCanvas.screenOffsetX); + screenPoint.y += ((renderingCanvas.height / 2) + renderingCanvas.screenOffsetY); + + return screenPoint; + } + + public selectRoomObject(roomId: number, objectId: number, objectCategory: number): void + { + if(!this._roomObjectEventHandler) return; + + this._roomObjectEventHandler._Str_17481(roomId, objectId, objectCategory); + } + + public _Str_8675(): void + { + if(!this._roomObjectEventHandler) return; + + this._roomObjectEventHandler._Str_8675(this._activeRoomId); + } + + private _Str_24651(k: Sprite, _arg_2: string, _arg_3: Texture, scale: number = 1): Sprite + { + if(!k || !_arg_3) return; + + let sprite = this._Str_16498(k, _arg_2); + + if(sprite) return null; + + sprite = Sprite.from(_arg_3); + + sprite.name = _arg_2; + + sprite.scale.set(scale); + + k.addChild(sprite); + + return sprite; + } + + public onRoomContentLoaded(id: number, assetName: string, success: boolean): void + { + if(!this._roomContentLoader || (id === -1)) return; + + this._thumbnailObjectIdBank._Str_15187((id - 1)); + + const listeners = this._thumbnailCallbacks.get(assetName); + + if(listeners) + { + this._thumbnailCallbacks.delete(assetName); + + const image = this._roomContentLoader.getImage(assetName); + + if(image) + { + for(const listener of listeners) + { + if(!listener) continue; + + listener.imageReady(id, null, image); + } + } + } + } + + public _Str_16645(objectId: number, category: number, _arg_3: boolean, instanceData: string = null, stuffData: IObjectData = null, state: number = -1, frameNumber: number = -1, posture: string = null): void + { + let type: string = null; + let colorIndex = 0; + let imageResult: ImageResult = null; + const scale = 1; + + if(_arg_3) + { + imageResult = this.getRoomObjectImage(this._activeRoomId, objectId, category, new Vector3d(), 1, null); + } + else + { + if(this._roomContentLoader) + { + if(category === RoomObjectCategory.FLOOR) + { + type = this._roomContentLoader.getFurnitureFloorNameForTypeId(objectId); + colorIndex = this._roomContentLoader.getFurnitureFloorColorIndex(objectId); + } + + else if(category === RoomObjectCategory.WALL) + { + type = this._roomContentLoader.getFurnitureWallNameForTypeId(objectId, instanceData); + colorIndex = this._roomContentLoader.getFurnitureWallColorIndex(objectId); + } + + if(category === RoomObjectCategory.UNIT) + { + type = RoomObjectUserType.getTypeString(objectId); + + if(type === 'pet') + { + type = this.getPetType(instanceData); + + const petFigureData = new PetFigureData(instanceData); + + imageResult = this.getRoomObjectPetImage(petFigureData.typeId, petFigureData.paletteId, petFigureData.color, new Vector3d(180), 64, null, true, 0, petFigureData.customParts, posture); + } + else + { + imageResult = this.getGenericRoomObjectImage(type, instanceData, new Vector3d(180), 64, null, 0, null, stuffData, state, frameNumber, posture); + } + } + else + { + imageResult = this.getGenericRoomObjectImage(type, colorIndex.toString(), new Vector3d(), 1, null, 0, instanceData, stuffData, state, frameNumber, posture); + } + } + } + + if(!imageResult || !imageResult.data) return; + + const canvas = this.getActiveRoomInstanceRenderingCanvas(); + + if(!canvas) return; + + const overlay = this.getRenderingCanvasOverlay(canvas); + + this._Str_21215(overlay, RoomEngine.OBJECT_ICON_SPRITE); + + const _local_15 = this._Str_24651(overlay, RoomEngine.OBJECT_ICON_SPRITE, imageResult.data, scale); + + if(_local_15) + { + _local_15.x = (this._activeRoomActiveCanvasMouseX - (imageResult.data.width / 2)); + _local_15.y = (this._activeRoomActiveCanvasMouseY - (imageResult.data.height / 2)); + } + } + + public getRoomObjectImage(roomId: number, objectId: number, category: number, direction: IVector3D, scale: number, listener: IGetImageListener, bgColor: number = 0): ImageResult + { + if(!this._roomManager) return null; + + let id = -1; + let type: string = null; + let data: IObjectData = null; + let color = ''; + let extras: string = null; + + const roomIdString = this.getRoomId(roomId); + const roomInstance = this._roomManager.getRoomInstance(roomIdString); + + if(roomInstance) + { + const roomObject = roomInstance.getRoomObject(objectId, category); + + if(roomObject && roomObject.model) + { + id = roomObject.id; + type = roomObject.type; + + switch(category) + { + case RoomObjectCategory.FLOOR: + case RoomObjectCategory.WALL: { + color = (roomObject.model.getValue(RoomObjectVariable.FURNITURE_COLOR).toString()); + extras = roomObject.model.getValue(RoomObjectVariable.FURNITURE_EXTRAS); + + const dataFormat = roomObject.model.getValue(RoomObjectVariable.FURNITURE_DATA_FORMAT); + + if(dataFormat !== LegacyDataType.FORMAT_KEY) + { + data = ObjectDataFactory.getData(dataFormat); + + data.initializeFromRoomObjectModel(roomObject.model); + } + + break; + } + case RoomObjectCategory.UNIT: + color = roomObject.model.getValue(RoomObjectVariable.FIGURE); + break; + } + } + } + + return this.getGenericRoomObjectImage(type, color, direction, scale, listener, bgColor, extras, data, -1, -1, null, id); + } + + public getFurnitureFloorIconUrl(typeId: number): string + { + let type: string = null; + let color = ''; + + if(this._roomContentLoader) + { + type = this._roomContentLoader.getFurnitureFloorNameForTypeId(typeId); + color = (this._roomContentLoader.getFurnitureFloorColorIndex(typeId).toString()); + + return this._roomContentLoader.getAssetIconUrl(type, color); + } + + return null; + } + + public getFurnitureFloorIcon(typeId: number, listener: IGetImageListener, extras: string = null, objectData: IObjectData = null): ImageResult + { + return this.getFurnitureFloorImage(typeId, new Vector3d(), 1, listener, 0, extras, -1, -1, objectData); + } + + public getFurnitureWallIconUrl(typeId: number, extra: string = null): string + { + let type: string = null; + let color = ''; + + if(this._roomContentLoader) + { + type = this._roomContentLoader.getFurnitureWallNameForTypeId(typeId, extra); + color = (this._roomContentLoader.getFurnitureWallColorIndex(typeId).toString()); + + return this._roomContentLoader.getAssetIconUrl(type, color); + } + + return null; + } + + public getFurnitureWallIcon(typeId: number, listener: IGetImageListener, extras: string = null): ImageResult + { + return this.getFurnitureWallImage(typeId, new Vector3d(), 1, listener, 0, extras); + } + + public getFurnitureFloorImage(typeId: number, direction: IVector3D, scale: number, listener: IGetImageListener, bgColor: number = 0, extras: string = null, state: number = -1, frameCount: number = -1, objectData: IObjectData = null): ImageResult + { + let type: string = null; + let color = ''; + + if(this._roomContentLoader) + { + type = this._roomContentLoader.getFurnitureFloorNameForTypeId(typeId); + color = (this._roomContentLoader.getFurnitureFloorColorIndex(typeId).toString()); + } + + if((scale === 1) && listener) + { + return this.getGenericRoomObjectThumbnail(type, color, listener, extras, objectData); + } + + return this.getGenericRoomObjectImage(type, color, direction, scale, listener, bgColor, extras, objectData, state, frameCount); + } + + public getFurnitureWallImage(typeId: number, direction: IVector3D, scale: number, listener: IGetImageListener, bgColor: number = 0, extras: string = null, state: number =-1, frameCount: number = -1): ImageResult + { + let type: string = null; + let color = ''; + + if(this._roomContentLoader) + { + type = this._roomContentLoader.getFurnitureWallNameForTypeId(typeId); + color = this._roomContentLoader.getFurnitureWallColorIndex(typeId).toString(); + } + + if((scale === 1) && listener) + { + return this.getGenericRoomObjectThumbnail(type, color, listener, extras, null); + } + + return this.getGenericRoomObjectImage(type, color, direction, scale, listener, bgColor, extras, null, state, frameCount); + } + + public getRoomObjectPetImage(typeId: number, paletteId: number, color: number, direction: IVector3D, scale: number, listener: IGetImageListener, _arg_7: boolean = true, bgColor: number = 0, customParts: PetCustomPart[] = null, posture: string = null): ImageResult + { + let type: string = null; + let value = ((((typeId + ' ') + paletteId) + ' ') + color.toString(16)); + + if(!_arg_7) value = (value + (' ' + 'head')); + + if(customParts) + { + value = (value + (' ' + customParts.length)); + + for(const _local_13 of customParts) + { + value = (value + (((((' ' + _local_13.layerId) + ' ') + _local_13.partId) + ' ') + _local_13.paletteId)); + } + } + + if(this._roomContentLoader) type = this._roomContentLoader.getPetNameForType(typeId); + + return this.getGenericRoomObjectImage(type, value, direction, scale, listener, bgColor, null, null, -1, -1, posture); + } + + public getGenericRoomObjectImage(type: string, value: string, direction: IVector3D, scale: number, listener: IGetImageListener, bgColor: number = 0, extras: string = null, objectData: IObjectData = null, state: number = -1, frameCount: number = -1, posture: string = null, originalId: number = -1): ImageResult + { + if(!this._roomManager) return null; + + const imageResult = new ImageResult(); + + imageResult.id = -1; + + if(!this._ready || !type) return imageResult; + + let roomInstance = this._roomManager.getRoomInstance(RoomEngine.TEMPORARY_ROOM); + + if(!roomInstance) + { + roomInstance = this._roomManager.createRoomInstance(RoomEngine.TEMPORARY_ROOM); + + if(!roomInstance) return imageResult; + } + + let objectId = this._imageObjectIdBank._Str_19709(); + const objectCategory = this.getRoomObjectCategoryForType(type); + + if(objectId < 0) return imageResult; + + objectId++; + + const roomObject = (roomInstance.createRoomObjectAndInitalize(objectId, type, objectCategory) as IRoomObjectController); + + if(!roomObject || !roomObject.model || !roomObject.logic) return imageResult; + + const model = roomObject.model; + + switch(objectCategory) + { + case RoomObjectCategory.FLOOR: + case RoomObjectCategory.WALL: + model.setValue(RoomObjectVariable.FURNITURE_COLOR, parseInt(value)); + model.setValue(RoomObjectVariable.FURNITURE_EXTRAS, extras); + break; + case RoomObjectCategory.UNIT: + if((type === RoomObjectUserType.USER) || (type === RoomObjectUserType.BOT) || (type === RoomObjectUserType.RENTABLE_BOT) || (type === RoomObjectUserType.PET)) + { + model.setValue(RoomObjectVariable.FIGURE, value); + } + else + { + const figureData = new PetFigureData(value); + + model.setValue(RoomObjectVariable.PET_PALETTE_INDEX, figureData.paletteId); + model.setValue(RoomObjectVariable.PET_COLOR, figureData.color); + + if(figureData.headOnly) model.setValue(RoomObjectVariable.PET_HEAD_ONLY, 1); + + if(figureData.hasCustomParts) + { + model.setValue(RoomObjectVariable.PET_CUSTOM_LAYER_IDS, figureData.customLayerIds); + model.setValue(RoomObjectVariable.PET_CUSTOM_PARTS_IDS, figureData.customPartIds); + model.setValue(RoomObjectVariable.PET_CUSTOM_PALETTE_IDS, figureData.customPaletteIds); + } + + if(posture) model.setValue(RoomObjectVariable.FIGURE_POSTURE, posture); + } + break; + case RoomObjectCategory.ROOM: + break; + } + + roomObject.setDirection(direction); + + const visualization = roomObject.visualization; + + if(!visualization) + { + roomInstance.removeRoomObject(objectId, objectCategory); + + return imageResult; + } + + if((state > -1) || objectData) + { + if(objectData && (objectData.getLegacyString() !== '')) + { + roomObject.logic.processUpdateMessage(new ObjectDataUpdateMessage(parseInt(objectData.getLegacyString()), objectData)); + } + else + { + roomObject.logic.processUpdateMessage(new ObjectDataUpdateMessage(state, objectData)); + } + } + + const geometry = new RoomGeometry(scale, new Vector3d(-135, 30, 0), new Vector3d(11, 11, 5)); + + visualization.update(geometry, 0, true, false); + + if(frameCount > 0) + { + let i = 0; + + while(i < frameCount) + { + visualization.update(geometry, 0, true, false); + + i++; + } + } + + const texture = visualization.getImage(bgColor, originalId); + + imageResult.data = texture; + imageResult.id = objectId; + + if(!this.isRoomContentTypeLoaded(type) && listener) + { + let imageListeners = this._imageCallbacks.get(objectId.toString()); + + if(!imageListeners) + { + imageListeners = []; + + this._imageCallbacks.set(objectId.toString(), imageListeners); + } + + imageListeners.push(listener); + + model.setValue(RoomObjectVariable.IMAGE_QUERY_SCALE, scale); + } + else + { + roomInstance.removeRoomObject(objectId, objectCategory); + + this._imageObjectIdBank._Str_15187((objectId - 1)); + + imageResult.id = 0; + } + + geometry.dispose(); + + return imageResult; + } + + public getGenericRoomObjectThumbnail(type: string, param: string, listener: IGetImageListener, extraData: string = null, stuffData: IObjectData = null): ImageResult + { + if(!this._roomManager) return null; + + const imageResult = new ImageResult(); + + imageResult.id = -1; + + if(!this._ready || !type) return imageResult; + + let roomInstance = this._roomManager.getRoomInstance(RoomEngine.TEMPORARY_ROOM); + + if(!roomInstance) + { + roomInstance = this._roomManager.createRoomInstance(RoomEngine.TEMPORARY_ROOM); + + if(!roomInstance) return imageResult; + } + + let objectId = this._thumbnailObjectIdBank._Str_19709(); + const objectCategory = this.getRoomObjectCategoryForType(type); + + if(objectId < 0) return imageResult; + + objectId++; + + imageResult.id = objectId; + imageResult.data = null; + imageResult.image = null; + + const assetName = [ type, param ].join('_'); + + const asset = this._roomContentLoader.getImage(assetName); + + if(!asset && listener) + { + let contentListeners = this._thumbnailCallbacks.get(assetName); + + if(!contentListeners) + { + contentListeners = []; + + this._thumbnailCallbacks.set(assetName, contentListeners); + + this._roomContentLoader.downloadImage(objectId, type, param, null); + } + + contentListeners.push(listener); + } + else + { + if(asset) + { + imageResult.image = asset; + } + + this._thumbnailObjectIdBank._Str_15187((objectId - 1)); + + imageResult.id = 0; + } + + return imageResult; + } + + public initalizeTemporaryObjectsByType(type: string, _arg_2: boolean): void + { + const roomInstance = this._roomManager.getRoomInstance(RoomEngine.TEMPORARY_ROOM); + + if(!roomInstance || !this._roomContentLoader) return; + + const objectCategory = this._roomContentLoader.getCategoryForType(type); + const objectManager = roomInstance.getManager(objectCategory); + + let geometry: RoomGeometry = null; + let scale = 0; + + if(objectManager && objectManager.objects.length) + { + for(const roomObject of objectManager.objects.getValues()) + { + if(roomObject && roomObject.model && (roomObject.type === type)) + { + const objectId = roomObject.id; + const visualization = roomObject.visualization; + + let texture: Texture = null; + + if(visualization) + { + const imageScale = roomObject.model.getValue(RoomObjectVariable.IMAGE_QUERY_SCALE); + + if(geometry && (scale !== imageScale)) + { + geometry.dispose(); + + geometry = null; + } + + if(!geometry) + { + scale = imageScale; + + geometry = new RoomGeometry(imageScale, new Vector3d(-135, 30, 0), new Vector3d(11, 11, 5)); + } + + visualization.update(geometry, 0, true, false); + + texture = visualization.image; + } + + roomInstance.removeRoomObject(objectId, objectCategory); + + this._imageObjectIdBank._Str_15187((objectId - 1)); + + const imageListeners = this._imageCallbacks.get(objectId.toString()); + + if(imageListeners) + { + this._imageCallbacks.delete(objectId.toString()); + + for(const imageListener of imageListeners) + { + if(!imageListener) continue; + + if(texture) imageListener.imageReady(objectId, texture); + else imageListener.imageFailed(objectId); + } + } + } + } + } + + if(geometry) geometry.dispose(); + } + + public _Str_7972(k: boolean): void + { + const canvas = this.getActiveRoomInstanceRenderingCanvas(); + + if(!canvas) return; + + const overlay = this.getRenderingCanvasOverlay(canvas); + const sprite = this._Str_16498(overlay, RoomEngine.OBJECT_ICON_SPRITE); + + if(sprite) + { + sprite.visible = k; + } + } + + public _Str_17948(): void + { + const canvas = this.getActiveRoomInstanceRenderingCanvas(); + + if(!canvas) return; + + const sprite = this.getRenderingCanvasOverlay(canvas); + + this._Str_21215(sprite, RoomEngine.OBJECT_ICON_SPRITE); + } + + private getRenderingCanvasOverlay(k: IRoomRenderingCanvas): Sprite + { + if(!k) return null; + + const displayObject = k.master as Container; + + if(!displayObject) return null; + + const sprite = displayObject.getChildByName(RoomEngine.OVERLAY) as Sprite; + + if(!sprite) return null; + + return sprite; + } + + private _Str_21215(k: Sprite, _arg_2: string): boolean + { + if(!k) return false; + + let index = (k.children.length - 1); + + while(index >= 0) + { + const child = k.getChildAt(index) as Sprite; + + if(child) + { + if(child.name === _arg_2) + { + k.removeChildAt(index); + + if(child.children.length) + { + const firstChild = child.getChildAt(0) as Sprite; + + firstChild.parent.removeChild(firstChild); + + firstChild.destroy(); + } + + return true; + } + } + + index--; + } + + return false; + } + + private _Str_16498(k: Sprite, _arg_2: string): Sprite + { + if(!k) return null; + + let index = (k.children.length - 1); + + while(index >= 0) + { + const child = k.getChildAt(index) as Sprite; + + if(child) + { + if(child.name === _arg_2) return child; + } + + index--; + } + + return null; + } + + public _Str_21072(k: number, _arg_2: number): IRoomObject[] + { + if(this._ready) + { + const _local_3 = this.getRoomId(k); + const _local_4 = this._roomManager.getRoomInstance(_local_3); + + + if(_local_4) return _local_4.getRoomObjectsForCategory(_arg_2); + } + + return []; + } + + protected _Str_21543(k: number, _arg_2: IRoomObject): void + { + const tileObjectMap = this.getRoomInstanceData(k).tileObjectMap; + + if(tileObjectMap) tileObjectMap._Str_21192(_arg_2); + } + + public _Str_17722(k: number, _arg_2: string): void + { + const tileObjectMap = this.getRoomInstanceData(k).tileObjectMap; + + if(tileObjectMap) tileObjectMap.populate(this._Str_21072(k, RoomObjectCategory.FLOOR)); + } + + public _Str_9972(k: Rectangle, _arg_2: number, _arg_3: boolean = false, _arg_4: boolean = true, _arg_5: boolean = false, canvasId: number = -1): IMessageComposer + { + let canvas: IRoomRenderingCanvas = null; + + if(canvasId > -1) + { + canvas = this.getRoomInstanceRenderingCanvas(this._activeRoomId, canvasId); + } + else + { + canvas = this.getActiveRoomInstanceRenderingCanvas(); + } + + if(!canvas) return null; + + if(_arg_5) + { + canvas._Str_20787(); + } + + let _local_8 = -1; + + if(((!(_arg_4)) && (!(this._roomSessionManager.getSession(this._activeRoomId) == null)))) + { + _local_8 = this._roomSessionManager.getSession(this._activeRoomId).ownRoomIndex; + } + + const _local_9 = new SpriteDataCollector(); + const _local_10 = _local_9._Str_4536(k, canvas, this, _local_8); + const _local_11 = _local_9._Str_24177(this); + const _local_12 = _local_9._Str_22985(k, canvas, this, _arg_2); + + if(_arg_5) canvas._Str_22174(); + + if(_arg_3) + { + //return new RenderRoomThumbnailMessageComposer(_local_12, _local_10, _local_11, this._activeRoomId, this._sessionDataManager._Str_8500); + } + + console.log(_local_10, _local_11, _local_12); + + //return new RenderRoomMessageComposer(_local_12, _local_10, _local_11, this._activeRoomId, this._sessionDataManager._Str_8500); + + return null; + } + + public createRoomScreenshot(roomId: number, canvasId: number): void + { + const canvas = this.getRoomInstanceRenderingCanvas(roomId, canvasId); + + if(!canvas) return; + + const texture = canvas.getDisplayAsTexture(); + + const base64 = Nitro.instance.renderer.extract.base64(texture); + + const image = new Image(); + + image.src = base64; + + const newWindow = window.open(''); + newWindow.document.write(image.outerHTML); + } + + public objectsInitialized(k: string): void + { + const roomId = this.getRoomIdFromString(k); + + this.events.dispatchEvent(new RoomEngineEvent(RoomEngineEvent.OBJECTS_INITIALIZED, roomId)); + } + + public getRoomId(id: number): string + { + return (id.toString()); + } + + private getRoomIdFromString(roomId: string): number + { + if(!roomId) return -1; + + const split = roomId.split('_'); + + if(split.length <= 0) return -1; + + return parseInt(split[0]); + } + + private getRoomObjectRoomId(object: IRoomObject): string + { + if(!object || !object.model) return null; + + return (object.model.getValue(RoomObjectVariable.OBJECT_ROOM_ID)); + } + + public getPetTypeId(figure: string): number + { + let type = -1; + + if(figure) + { + const parts = figure.split(' '); + + if(parts.length > 1) type = parseInt(parts[0]); + } + + return type; + } + + private getPetType(type: string): string + { + if(!type) return null; + + const parts = type.split(' '); + + if(parts.length > 1) + { + const typeId = parseInt(parts[0]); + + if(this._roomContentLoader) return this._roomContentLoader.getPetNameForType(typeId); + + return 'pet'; + } + + return null; + } + + public isRoomContentTypeLoaded(name: string): boolean + { + if(!this._roomContentLoader) return false; + + return (this._roomContentLoader.getCollection(name) !== null); + } + + public modifyRoomObjectData(objectId: number, objectCategory: number, colorHex: string, text: string): boolean + { + if(!this._roomObjectEventHandler || (objectCategory !== RoomObjectCategory.WALL)) return false; + + return (this._roomObjectEventHandler.modifyWallItemData(this._activeRoomId, objectId, colorHex, text)); + } + + public deleteRoomObject(objectId: number, objectCategory: number): boolean + { + if(!this._roomObjectEventHandler || (objectCategory !== RoomObjectCategory.WALL)) return false; + + return this._roomObjectEventHandler.deleteWallItem(this._activeRoomId, objectId); + } + + public get connection(): IConnection + { + return this._communication.connection; + } + + public get sessionDataManager(): ISessionDataManager + { + return this._sessionDataManager; + } + + public set sessionDataManager(manager: ISessionDataManager) + { + this._sessionDataManager = manager; + } + + public get roomSessionManager(): IRoomSessionManager + { + return this._roomSessionManager; + } + + public set roomSessionManager(manager: IRoomSessionManager) + { + this._roomSessionManager = manager; + } + + public get roomManager(): IRoomManager + { + return this._roomManager; + } + + public set roomManager(manager: IRoomManager) + { + this._roomManager = manager; + } + + public get objectEventHandler(): RoomObjectEventHandler + { + return this._roomObjectEventHandler; + } + + public get roomRendererFactory(): IRoomRendererFactory + { + return this._roomRendererFactory; + } + + public get visualizationFactory(): IRoomObjectVisualizationFactory + { + return this._visualizationFactory; + } + + public get logicFactory(): IRoomObjectLogicFactory + { + return this._logicFactory; + } + + public get activeRoomId(): number + { + return this._activeRoomId; + } + + public get ready(): boolean + { + return this._ready; + } + + public get roomContentLoader(): RoomContentLoader + { + return this._roomContentLoader; + } + + public get isDecorating(): boolean + { + if(!this._roomSessionManager) return false; + + const session = this._roomSessionManager.getSession(this._activeRoomId); + + return (session && session.isDecorating) || false; + } + + private get _Str_11555(): boolean + { + return true; + } + + public get selectedAvatarId(): number + { + if(!this._roomObjectEventHandler) return -1; + + return this._roomObjectEventHandler.selectedAvatarId; + } + + public getRoomObjectCount(roomId: number, categoryId: number): number + { + if(this._roomManager == null) return 0; + + return this._roomManager.getRoomInstance(roomId.toString()).getRoomObjectsForCategory(categoryId).length; + } +} diff --git a/src/nitro/room/RoomMessageHandler.ts b/src/nitro/room/RoomMessageHandler.ts new file mode 100644 index 00000000..f04469aa --- /dev/null +++ b/src/nitro/room/RoomMessageHandler.ts @@ -0,0 +1,968 @@ +import { Disposable } from '../../core/common/disposable/Disposable'; +import { IConnection } from '../../core/communication/connections/IConnection'; +import { IVector3D } from '../../room/utils/IVector3D'; +import { Vector3d } from '../../room/utils/Vector3d'; +import { PetType } from '../avatar/pets/PetType'; +import { ObjectsRollingEvent } from '../communication/messages/incoming/room/engine/ObjectsRollingEvent'; +import { FurnitureFloorAddEvent } from '../communication/messages/incoming/room/furniture/floor/FurnitureFloorAddEvent'; +import { FurnitureFloorEvent } from '../communication/messages/incoming/room/furniture/floor/FurnitureFloorEvent'; +import { FurnitureFloorRemoveEvent } from '../communication/messages/incoming/room/furniture/floor/FurnitureFloorRemoveEvent'; +import { FurnitureFloorUpdateEvent } from '../communication/messages/incoming/room/furniture/floor/FurnitureFloorUpdateEvent'; +import { FurnitureAliasesEvent } from '../communication/messages/incoming/room/furniture/FurnitureAliasesEvent'; +import { FurnitureDataEvent } from '../communication/messages/incoming/room/furniture/FurnitureDataEvent'; +import { FurnitureItemDataEvent } from '../communication/messages/incoming/room/furniture/FurnitureItemDataEvent'; +import { FurnitureState2Event } from '../communication/messages/incoming/room/furniture/FurnitureState2Event'; +import { FurnitureStateEvent } from '../communication/messages/incoming/room/furniture/FurnitureStateEvent'; +import { FurnitureWallAddEvent } from '../communication/messages/incoming/room/furniture/wall/FurnitureWallAddEvent'; +import { FurnitureWallEvent } from '../communication/messages/incoming/room/furniture/wall/FurnitureWallEvent'; +import { FurnitureWallRemoveEvent } from '../communication/messages/incoming/room/furniture/wall/FurnitureWallRemoveEvent'; +import { FurnitureWallUpdateEvent } from '../communication/messages/incoming/room/furniture/wall/FurnitureWallUpdateEvent'; +import { RoomDoorEvent } from '../communication/messages/incoming/room/mapping/RoomDoorEvent'; +import { RoomHeightMapEvent } from '../communication/messages/incoming/room/mapping/RoomHeightMapEvent'; +import { RoomHeightMapUpdateEvent } from '../communication/messages/incoming/room/mapping/RoomHeightMapUpdateEvent'; +import { RoomModelEvent } from '../communication/messages/incoming/room/mapping/RoomModelEvent'; +import { RoomModelNameEvent } from '../communication/messages/incoming/room/mapping/RoomModelNameEvent'; +import { RoomPaintEvent } from '../communication/messages/incoming/room/mapping/RoomPaintEvent'; +import { RoomThicknessEvent } from '../communication/messages/incoming/room/mapping/RoomThicknessEvent'; +import { PetFigureUpdateEvent } from '../communication/messages/incoming/room/pet/PetFigureUpdateEvent'; +import { YouArePlayingGameEvent } from '../communication/messages/incoming/room/session/YouArePlayingGameEvent'; +import { RoomUnitChatEvent } from '../communication/messages/incoming/room/unit/chat/RoomUnitChatEvent'; +import { RoomUnitChatShoutEvent } from '../communication/messages/incoming/room/unit/chat/RoomUnitChatShoutEvent'; +import { RoomUnitChatWhisperEvent } from '../communication/messages/incoming/room/unit/chat/RoomUnitChatWhisperEvent'; +import { RoomUnitTypingEvent } from '../communication/messages/incoming/room/unit/chat/RoomUnitTypingEvent'; +import { RoomUnitDanceEvent } from '../communication/messages/incoming/room/unit/RoomUnitDanceEvent'; +import { RoomUnitEffectEvent } from '../communication/messages/incoming/room/unit/RoomUnitEffectEvent'; +import { RoomUnitEvent } from '../communication/messages/incoming/room/unit/RoomUnitEvent'; +import { RoomUnitExpressionEvent } from '../communication/messages/incoming/room/unit/RoomUnitExpressionEvent'; +import { RoomUnitHandItemEvent } from '../communication/messages/incoming/room/unit/RoomUnitHandItemEvent'; +import { RoomUnitIdleEvent } from '../communication/messages/incoming/room/unit/RoomUnitIdleEvent'; +import { RoomUnitInfoEvent } from '../communication/messages/incoming/room/unit/RoomUnitInfoEvent'; +import { RoomUnitNumberEvent } from '../communication/messages/incoming/room/unit/RoomUnitNumberEvent'; +import { RoomUnitRemoveEvent } from '../communication/messages/incoming/room/unit/RoomUnitRemoveEvent'; +import { RoomUnitStatusEvent } from '../communication/messages/incoming/room/unit/RoomUnitStatusEvent'; +import { UserInfoEvent } from '../communication/messages/incoming/user/data/UserInfoEvent'; +import { IgnoreResultEvent } from '../communication/messages/incoming/user/IgnoreResultEvent'; +import { FurnitureAliasesComposer } from '../communication/messages/outgoing/room/furniture/FurnitureAliasesComposer'; +import { RoomModelComposer } from '../communication/messages/outgoing/room/mapping/RoomModelComposer'; +import { FurnitureFloorDataParser } from '../communication/messages/parser/room/furniture/floor/FurnitureFloorDataParser'; +import { FurnitureWallDataParser } from '../communication/messages/parser/room/furniture/wall/FurnitureWallDataParser'; +import { RoomDoorParser } from '../communication/messages/parser/room/mapping/RoomDoorParser'; +import { IRoomCreator } from './IRoomCreator'; +import { LegacyDataType } from './object/data/type/LegacyDataType'; +import { RoomObjectUserType } from './object/RoomObjectUserType'; +import { RoomObjectVariable } from './object/RoomObjectVariable'; +import { RoomPlaneParser } from './object/RoomPlaneParser'; +import { RoomVariableEnum } from './RoomVariableEnum'; +import { FurnitureStackingHeightMap } from './utils/FurnitureStackingHeightMap'; +import { LegacyWallGeometry } from './utils/LegacyWallGeometry'; +import { ObjectRolling } from './utils/ObjectRolling'; + +export class RoomMessageHandler extends Disposable +{ + private _connection: IConnection; + private _roomCreator: IRoomCreator; + private _planeParser: RoomPlaneParser; + private _latestEntryTileEvent: RoomDoorEvent; + + private _currentRoomId: number; + private _ownUserId: number; + private _initialConnection: boolean; + + constructor(roomCreator: IRoomCreator) + { + super(); + + this._connection = null; + this._roomCreator = roomCreator; + this._planeParser = new RoomPlaneParser(); + this._latestEntryTileEvent = null; + + this._currentRoomId = 0; + this._ownUserId = 0; + this._initialConnection = true; + } + + protected onDispose(): void + { + super.onDispose(); + + this._connection = null; + this._roomCreator = null; + this._latestEntryTileEvent = null; + + if(this._planeParser) + { + this._planeParser.dispose(); + + this._planeParser = null; + } + } + + public setConnection(connection: IConnection) + { + if(this._connection || !connection) return; + + this._connection = connection; + + this._connection.addMessageEvent(new UserInfoEvent(this.onUserInfoEvent.bind(this))); + this._connection.addMessageEvent(new RoomModelNameEvent(this.onRoomModelNameEvent.bind(this))); + this._connection.addMessageEvent(new RoomPaintEvent(this.onRoomPaintEvent.bind(this))); + this._connection.addMessageEvent(new RoomModelEvent(this.onRoomModelEvent.bind(this))); + this._connection.addMessageEvent(new RoomHeightMapEvent(this.onRoomHeightMapEvent.bind(this))); + this._connection.addMessageEvent(new RoomHeightMapUpdateEvent(this.onRoomHeightMapUpdateEvent.bind(this))); + this._connection.addMessageEvent(new RoomThicknessEvent(this.onRoomThicknessEvent.bind(this))); + this._connection.addMessageEvent(new RoomDoorEvent(this.onRoomDoorEvent.bind(this))); + this._connection.addMessageEvent(new ObjectsRollingEvent(this.onRoomRollingEvent.bind(this))); + this._connection.addMessageEvent(new FurnitureAliasesEvent(this.onFurnitureAliasesEvent.bind(this))); + this._connection.addMessageEvent(new FurnitureFloorAddEvent(this.onFurnitureFloorAddEvent.bind(this))); + this._connection.addMessageEvent(new FurnitureFloorEvent(this.onFurnitureFloorEvent.bind(this))); + this._connection.addMessageEvent(new FurnitureFloorRemoveEvent(this.onFurnitureFloorRemoveEvent.bind(this))); + this._connection.addMessageEvent(new FurnitureFloorUpdateEvent(this.onFurnitureFloorUpdateEvent.bind(this))); + this._connection.addMessageEvent(new FurnitureWallAddEvent(this.onFurnitureWallAddEvent.bind(this))); + this._connection.addMessageEvent(new FurnitureWallEvent(this.onFurnitureWallEvent.bind(this))); + this._connection.addMessageEvent(new FurnitureWallRemoveEvent(this.onFurnitureWallRemoveEvent.bind(this))); + this._connection.addMessageEvent(new FurnitureWallUpdateEvent(this.onFurnitureWallUpdateEvent.bind(this))); + this._connection.addMessageEvent(new FurnitureDataEvent(this.onFurnitureDataEvent.bind(this))); + this._connection.addMessageEvent(new FurnitureItemDataEvent(this.onFurnitureItemDataEvent.bind(this))); + this._connection.addMessageEvent(new FurnitureStateEvent(this.onFurnitureStateEvent.bind(this))); + this._connection.addMessageEvent(new RoomUnitDanceEvent(this.onRoomUnitDanceEvent.bind(this))); + this._connection.addMessageEvent(new RoomUnitEffectEvent(this.onRoomUnitEffectEvent.bind(this))); + this._connection.addMessageEvent(new RoomUnitEvent(this.onRoomUnitEvent.bind(this))); + this._connection.addMessageEvent(new RoomUnitExpressionEvent(this.onRoomUnitExpressionEvent.bind(this))); + this._connection.addMessageEvent(new RoomUnitHandItemEvent(this.onRoomUnitHandItemEvent.bind(this))); + this._connection.addMessageEvent(new RoomUnitIdleEvent(this.onRoomUnitIdleEvent.bind(this))); + this._connection.addMessageEvent(new RoomUnitInfoEvent(this.onRoomUnitInfoEvent.bind(this))); + this._connection.addMessageEvent(new RoomUnitNumberEvent(this.onRoomUnitNumberEvent.bind(this))); + this._connection.addMessageEvent(new RoomUnitRemoveEvent(this.onRoomUnitRemoveEvent.bind(this))); + this._connection.addMessageEvent(new RoomUnitStatusEvent(this.onRoomUnitStatusEvent.bind(this))); + this._connection.addMessageEvent(new RoomUnitChatEvent(this.onRoomUnitChatEvent.bind(this))); + this._connection.addMessageEvent(new RoomUnitChatShoutEvent(this.onRoomUnitChatEvent.bind(this))); + this._connection.addMessageEvent(new RoomUnitChatWhisperEvent(this.onRoomUnitChatEvent.bind(this))); + this._connection.addMessageEvent(new RoomUnitTypingEvent(this.onRoomUnitTypingEvent.bind(this))); + this._connection.addMessageEvent(new PetFigureUpdateEvent(this.onPetFigureUpdateEvent.bind(this))); + this._connection.addMessageEvent(new YouArePlayingGameEvent(this.onYouArePlayingGameEvent.bind(this))); + this._connection.addMessageEvent(new FurnitureState2Event(this.onFurnitureState2Event.bind(this))); + this._connection.addMessageEvent(new IgnoreResultEvent(this.onIgnoreResultEvent.bind(this))); + } + + public setRoomId(id: number): void + { + if(this._currentRoomId !== 0) + { + if(this._roomCreator) this._roomCreator.destroyRoom(this._currentRoomId); + } + + this._currentRoomId = id; + this._latestEntryTileEvent = null; + } + + public clearRoomId(): void + { + this._currentRoomId = 0; + this._latestEntryTileEvent = null; + } + + private onUserInfoEvent(event: UserInfoEvent): void + { + if(!(event instanceof UserInfoEvent) || !event.connection) return; + + const parser = event.getParser(); + + if(!parser) return; + + this._ownUserId = parser.userInfo.userId; + } + + private onRoomModelNameEvent(event: RoomModelNameEvent): void + { + if(!(event instanceof RoomModelNameEvent) || !event.connection) return; + + if(this._currentRoomId !== event.getParser().roomId) + { + this.setRoomId(event.getParser().roomId); + } + + if(this._roomCreator) + { + this._roomCreator.setRoomInstanceModelName(event.getParser().roomId, event.getParser().name); + } + + if(this._initialConnection) + { + event.connection.send(new FurnitureAliasesComposer()); + + this._initialConnection = false; + + return; + } + + event.connection.send(new RoomModelComposer()); + } + + private onRoomPaintEvent(event: RoomPaintEvent): void + { + if(!(event instanceof RoomPaintEvent)) return; + + const parser = event.getParser(); + + if(!parser) return; + + const floorType = parser.floorType; + const wallType = parser.wallType; + const landscapeType = parser.landscapeType; + + if(this._roomCreator) + { + this._roomCreator.updateRoomInstancePlaneType(this._currentRoomId, floorType, wallType, landscapeType); + } + } + + private onRoomModelEvent(event: RoomModelEvent): void + { + if(!(event instanceof RoomModelEvent) || !event.connection || !this._roomCreator) return; + + const parser = event.getParser(); + + if(!parser) return; + + const wallGeometry = this._roomCreator.getLegacyWallGeometry(this._currentRoomId); + + if(!wallGeometry) return; + + this._planeParser.reset(); + + const width = parser.width; + const height = parser.height; + + this._planeParser.initializeTileMap(width, height); + + let entryTile: RoomDoorParser = null; + + if(this._latestEntryTileEvent) entryTile = this._latestEntryTileEvent.getParser(); + + let doorX = -1; + let doorY = -1; + let doorZ = 0; + let doorDirection = 0; + + let y = 0; + + while(y < height) + { + let x = 0; + + while(x < width) + { + const tileHeight = parser.getHeight(x, y); + + if(((((y > 0) && (y < (height - 1))) || ((x > 0) && (x < (width - 1)))) && (!(tileHeight == RoomPlaneParser.TILE_BLOCKED))) && ((entryTile == null) || ((x == entryTile.x) && (y == entryTile.y)))) + { + if(((parser.getHeight(x, (y - 1)) == RoomPlaneParser.TILE_BLOCKED) && (parser.getHeight((x - 1), y) == RoomPlaneParser.TILE_BLOCKED)) && (parser.getHeight(x, (y + 1)) == RoomPlaneParser.TILE_BLOCKED)) + { + doorX = (x + 0.5); + doorY = y; + doorZ = tileHeight; + doorDirection = 90; + } + + if(((parser.getHeight(x, (y - 1)) == RoomPlaneParser.TILE_BLOCKED) && (parser.getHeight((x - 1), y) == RoomPlaneParser.TILE_BLOCKED)) && (parser.getHeight((x + 1), y) == RoomPlaneParser.TILE_BLOCKED)) + { + doorX = x; + doorY = (y + 0.5); + doorZ = tileHeight; + doorDirection = 180; + } + } + + this._planeParser.setTileHeight(x, y, tileHeight); + + x++; + } + + y++; + } + + this._planeParser.setTileHeight(Math.floor(doorX), Math.floor(doorY), doorZ); + this._planeParser.initializeFromTileData(parser.wallHeight); + this._planeParser.setTileHeight(Math.floor(doorX), Math.floor(doorY), (doorZ + this._planeParser.wallHeight)); + + if(parser.scale === 64) + { + this._planeParser.restrictsDragging = true; + this._planeParser.restrictsScaling = true; + this._planeParser.restrictedScale = 0.5; + } + else + { + this._planeParser.restrictsDragging = false; + this._planeParser.restrictsScaling = false; + this._planeParser.restrictedScale = 1; + } + + wallGeometry.scale = LegacyWallGeometry.DEFAULT_SCALE; + wallGeometry.initialize(width, height, this._planeParser.floorHeight); + + let heightIterator = (parser.height - 1); + + while(heightIterator >= 0) + { + let widthIterator = (parser.width - 1); + + while(widthIterator >= 0) + { + wallGeometry.setHeight(widthIterator, heightIterator, this._planeParser.getTileHeight(widthIterator, heightIterator)); + widthIterator--; + } + + heightIterator--; + } + + const roomMap = this._planeParser.getMapData(); + + roomMap.doors.push({ + x: doorX, + y: doorY, + z: doorZ, + dir: doorDirection + }); + + this._roomCreator.createRoomInstance(this._currentRoomId, roomMap); + } + + private onRoomHeightMapEvent(event: RoomHeightMapEvent): void + { + if(!(event instanceof RoomHeightMapEvent) || !event.connection || !this._roomCreator) return; + + const parser = event.getParser(); + + if(!parser) return; + + const width = parser.width; + const height = parser.height; + const heightMap = new FurnitureStackingHeightMap(width, height); + + let y = 0; + + while(y < height) + { + let x = 0; + + while(x < width) + { + heightMap.setTileHeight(x, y, parser.getTileHeight(x, y)); + heightMap.setStackingBlocked(x, y, parser.getStackingBlocked(x, y)); + heightMap.setIsRoomTile(x, y, parser.isRoomTile(x, y)); + + x++; + } + + y++; + } + + this._roomCreator.setFurnitureStackingHeightMap(this._currentRoomId, heightMap); + } + + private onRoomHeightMapUpdateEvent(event: RoomHeightMapUpdateEvent): void + { + if(!(event instanceof RoomHeightMapUpdateEvent) || !event.connection || !this._roomCreator) return; + + const parser = event.getParser(); + + if(!parser) return; + + const heightMap = this._roomCreator.getFurnitureStackingHeightMap(this._currentRoomId); + + if(!heightMap) return; + + while(parser.next()) + { + heightMap.setTileHeight(parser.x, parser.y, parser.tileHeight()); + heightMap.setStackingBlocked(parser.x, parser.y, parser.isStackingBlocked()); + heightMap.setIsRoomTile(parser.x, parser.y, parser.isRoomTile()); + } + + this._roomCreator._Str_17722(this._currentRoomId, 'RoomMessageHandler.onRoomHeightMapUpdateEvent()'); + } + + private onRoomThicknessEvent(event: RoomThicknessEvent): void + { + if(!(event instanceof RoomThicknessEvent)) return; + + const parser = event.getParser(); + + if(!parser) return; + + const visibleWall = !parser.hideWalls; + const visibleFloor = true; + const thicknessWall = parser.thicknessWall; + const thicknessFloor = parser.thicknessFloor; + + if(this._roomCreator) + { + this._roomCreator.updateRoomInstancePlaneVisibility(this._currentRoomId, visibleWall, visibleFloor); + this._roomCreator.updateRoomInstancePlaneThickness(this._currentRoomId, thicknessWall, thicknessFloor); + } + } + + private onRoomDoorEvent(event: RoomDoorEvent): void + { + if(!(event instanceof RoomDoorEvent)) return; + + this._latestEntryTileEvent = event; + } + + private onRoomRollingEvent(event: ObjectsRollingEvent): void + { + if(!(event instanceof ObjectsRollingEvent) || !event.connection || !this._roomCreator) return; + + const parser = event.getParser(); + + this._roomCreator.updateRoomObjectFloor(this._currentRoomId, parser.rollerId, null, null, 1, null); + this._roomCreator.updateRoomObjectFloor(this._currentRoomId, parser.rollerId, null, null, 2, null); + + const furnitureRolling = parser.itemsRolling; + + if(furnitureRolling && furnitureRolling.length) + { + for(const rollData of furnitureRolling) + { + if(!rollData) continue; + + this._roomCreator.rollRoomObjectFloor(this._currentRoomId, rollData.id, rollData.location, rollData.targetLocation); + } + } + + const unitRollData = parser.unitRolling; + + if(unitRollData) + { + this._roomCreator.updateRoomObjectUserLocation(this._currentRoomId, unitRollData.id, unitRollData.location, unitRollData.targetLocation); + + const object = this._roomCreator.getRoomObjectUser(this._currentRoomId, unitRollData.id); + + if(object && object.type !== RoomObjectUserType.MONSTER_PLANT) + { + let posture = 'std'; + + switch(unitRollData.movementType) + { + case ObjectRolling.MOVE: + posture = 'mv'; + break; + case ObjectRolling.SLIDE: + posture = 'std'; + break; + } + + this._roomCreator.updateRoomObjectUserPosture(this._currentRoomId, unitRollData.id, posture); + } + } + } + + private onFurnitureAliasesEvent(event: FurnitureAliasesEvent): void + { + if(!(event instanceof FurnitureAliasesEvent) || !event.connection || !this._roomCreator) return; + + const alises = event.getParser().aliases; + + this._connection.send(new RoomModelComposer()); + } + + private onFurnitureFloorAddEvent(event: FurnitureFloorAddEvent): void + { + if(!(event instanceof FurnitureFloorAddEvent) || !event.connection || !this._roomCreator) return; + + const item = event.getParser().item; + + if(!item) return; + + this.addRoomObjectFurnitureFloor(this._currentRoomId, item); + } + + private onFurnitureFloorEvent(event: FurnitureFloorEvent): void + { + if(!(event instanceof FurnitureFloorEvent) || !event.connection || !this._roomCreator) return; + + const parser = event.getParser(); + + if(!parser) return; + + const totalObjects = parser.items.length; + + let iterator = 0; + + while(iterator < totalObjects) + { + const object = parser.items[iterator]; + + if(object) this.addRoomObjectFurnitureFloor(this._currentRoomId, object); + + iterator++; + } + } + + private onFurnitureFloorRemoveEvent(event: FurnitureFloorRemoveEvent): void + { + if(!(event instanceof FurnitureFloorRemoveEvent) || !event.connection || !this._roomCreator) return; + + const parser = event.getParser(); + + if(!parser) return; + + if(parser.delay > 0) + { + setTimeout(() => + { + this._roomCreator.removeRoomObjectFloor(this._currentRoomId, parser.itemId, (parser.isExpired) ? -1 : parser.userId, true); + }, parser.delay); + } + else + { + this._roomCreator.removeRoomObjectFloor(this._currentRoomId, parser.itemId, (parser.isExpired) ? -1 : parser.userId, true); + } + } + + private onFurnitureFloorUpdateEvent(event: FurnitureFloorUpdateEvent): void + { + if(!(event instanceof FurnitureFloorUpdateEvent) || !event.connection || !this._roomCreator) return; + + const item = event.getParser().item; + + if(!item) return; + + const location: IVector3D = new Vector3d(item.x, item.y, item.z); + const direction: IVector3D = new Vector3d(item.direction); + + this._roomCreator.updateRoomObjectFloor(this._currentRoomId, item.itemId, location, direction, item.data.state, item.data, item.extra); + this._roomCreator.updateRoomObjectFloorHeight(this._currentRoomId, item.itemId, item.stackHeight); + this._roomCreator.updateRoomObjectFloorExpiration(this._currentRoomId, item.itemId, item.expires); + } + + private onFurnitureWallAddEvent(event: FurnitureWallAddEvent): void + { + if(!(event instanceof FurnitureWallAddEvent) || !event.connection || !this._roomCreator) return; + + const data = event.getParser().item; + + if(!data) return; + + this.addRoomObjectFurnitureWall(this._currentRoomId, data); + } + + private onFurnitureWallEvent(event: FurnitureWallEvent): void + { + if(!(event instanceof FurnitureWallEvent) || !event.connection || !this._roomCreator) return; + + const parser = event.getParser(); + + if(!parser) return; + + const totalObjects = parser.items.length; + + let iterator = 0; + + while(iterator < totalObjects) + { + const data = parser.items[iterator]; + + if(data) this.addRoomObjectFurnitureWall(this._currentRoomId, data); + + iterator++; + } + } + + private onFurnitureWallRemoveEvent(event: FurnitureWallRemoveEvent): void + { + if(!(event instanceof FurnitureWallRemoveEvent) || !event.connection || !this._roomCreator) return; + + const parser = event.getParser(); + + if(!parser) return; + + this._roomCreator.removeRoomObjectWall(this._currentRoomId, parser.itemId, parser.userId); + } + + private onFurnitureWallUpdateEvent(event: FurnitureWallUpdateEvent): void + { + if(!(event instanceof FurnitureWallUpdateEvent) || !event.connection || !this._roomCreator) return; + + const wallGeometry = this._roomCreator.getLegacyWallGeometry(this._currentRoomId); + + if(!wallGeometry) return; + + const item = event.getParser().item; + + if(!item) return; + + const location = wallGeometry.getLocation(item.width, item.height, item.localX, item.localY, item.direction); + const direction = new Vector3d(wallGeometry.getDirection(item.direction)); + + this._roomCreator.updateRoomObjectWall(this._currentRoomId, item.itemId, location, direction, item.state, item.stuffData); + this._roomCreator.updateRoomObjectWallExpiration(this._currentRoomId, item.itemId, item.secondsToExpiration); + } + + private onFurnitureDataEvent(event: FurnitureDataEvent): void + { + if(!(event instanceof FurnitureDataEvent) || !event.connection || !this._roomCreator) return; + + const parser = event.getParser(); + + this._roomCreator.updateRoomObjectFloor(this._currentRoomId, parser.furnitureId, null, null, parser.objectData.state, parser.objectData); + } + + private onFurnitureItemDataEvent(event: FurnitureItemDataEvent): void + { + if(!(event instanceof FurnitureItemDataEvent) || !event.connection || !this._roomCreator) return; + + const parser = event.getParser(); + + this._roomCreator.updateRoomObjectWallItemData(this._currentRoomId, parser.furnitureId, parser.data); + } + + private onFurnitureStateEvent(event: FurnitureStateEvent): void + { + if(!(event instanceof FurnitureStateEvent) || !event.connection || !this._roomCreator) return; + + const parser = event.getParser(); + + this._roomCreator.updateRoomObjectFloor(this._currentRoomId, parser.itemId, null, null, parser.state, new LegacyDataType()); + } + + private onFurnitureState2Event(event: FurnitureState2Event): void + { + if(!(event instanceof FurnitureState2Event) || !event.connection || !this._roomCreator) return; + + const parser = event.getParser(); + + this._roomCreator.updateRoomObjectFloor(this._currentRoomId, parser.itemId, null, null, parser.value, new LegacyDataType()); + } + + private onRoomUnitDanceEvent(event: RoomUnitDanceEvent): void + { + if(!(event instanceof RoomUnitDanceEvent) || !event.connection || !this._roomCreator) return; + + this._roomCreator.updateRoomObjectUserAction(this._currentRoomId, event.getParser().unitId, RoomObjectVariable.FIGURE_DANCE, event.getParser().danceId); + } + + private onRoomUnitEffectEvent(event: RoomUnitEffectEvent): void + { + if(!(event instanceof RoomUnitEffectEvent) || !event.connection || !this._roomCreator) return; + + this._roomCreator.updateRoomObjectUserEffect(this._currentRoomId, event.getParser().unitId, event.getParser().effectId, event.getParser().delay); + } + + private onRoomUnitEvent(event: RoomUnitEvent): void + { + if(!(event instanceof RoomUnitEvent) || !event.connection || !this._roomCreator) return; + + const users = event.getParser().users; + + if(!users || !users.length) return; + + for(const user of users) + { + if(!user) continue; + + const location = new Vector3d(user.x, user.y, user.z); + const direction = new Vector3d(user.dir); + + this._roomCreator.addRoomObjectUser(this._currentRoomId, user.roomIndex, location, direction, user.dir, user.userType, user.figure); + + if(user.webID === this._ownUserId) + { + this._roomCreator.setRoomSessionOwnUser(this._currentRoomId, user.roomIndex); + this._roomCreator.updateRoomObjectUserOwn(this._currentRoomId, user.roomIndex); + } + + this._roomCreator.updateRoomObjectUserFigure(this._currentRoomId, user.roomIndex, user.figure, user.sex, user.subType, user.isRiding); + + if(RoomObjectUserType.getTypeString(user.userType) === RoomObjectUserType.PET) + { + if(this._roomCreator.getPetTypeId(user.figure) === PetType.MONSTERPLANT) + { + this._roomCreator.updateRoomObjectUserPosture(this._currentRoomId, user.roomIndex, user.petPosture); + } + } + + this._roomCreator.updateRoomObjectUserAction(this._currentRoomId, user.roomIndex, RoomObjectVariable.FIGURE_IS_MUTED, (this._roomCreator.sessionDataManager.isUserIgnored(user.name) ? 1 : 0)); + } + } + + private onRoomUnitExpressionEvent(event: RoomUnitExpressionEvent): void + { + if(!(event instanceof RoomUnitExpressionEvent) || !event.connection || !this._roomCreator) return; + + this._roomCreator.updateRoomObjectUserAction(this._currentRoomId, event.getParser().unitId, RoomObjectVariable.FIGURE_EXPRESSION, event.getParser().expression); + } + + private onRoomUnitHandItemEvent(event: RoomUnitHandItemEvent): void + { + if(!(event instanceof RoomUnitHandItemEvent) || !event.connection || !this._roomCreator) return; + + this._roomCreator.updateRoomObjectUserAction(this._currentRoomId, event.getParser().unitId, RoomObjectVariable.FIGURE_CARRY_OBJECT, event.getParser().handId); + } + + private onRoomUnitIdleEvent(event: RoomUnitIdleEvent): void + { + if(!(event instanceof RoomUnitIdleEvent) || !event.connection || !this._roomCreator) return; + + this._roomCreator.updateRoomObjectUserAction(this._currentRoomId, event.getParser().unitId, RoomObjectVariable.FIGURE_SLEEP, (event.getParser().isIdle ? 1 : 0)); + } + + private onRoomUnitInfoEvent(event: RoomUnitInfoEvent): void + { + if(!(event instanceof RoomUnitInfoEvent) || !event.connection || !this._roomCreator) return; + + this._roomCreator.updateRoomObjectUserFigure(this._currentRoomId, event.getParser().unitId, event.getParser().figure, event.getParser().gender); + } + + private onRoomUnitNumberEvent(event: RoomUnitNumberEvent): void + { + if(!(event instanceof RoomUnitNumberEvent) || !event.connection || !this._roomCreator) return; + + const parser = event.getParser(); + + if(!parser) return; + + this._roomCreator.updateRoomObjectUserAction(this._currentRoomId, parser.unitId, RoomObjectVariable.FIGURE_NUMBER_VALUE, parser.value); + } + + private onRoomUnitRemoveEvent(event: RoomUnitRemoveEvent): void + { + if(!(event instanceof RoomUnitRemoveEvent) || !event.connection || !this._roomCreator) return; + + this._roomCreator.removeRoomObjectUser(this._currentRoomId, event.getParser().unitId); + } + + private onRoomUnitStatusEvent(event: RoomUnitStatusEvent): void + { + if(!(event instanceof RoomUnitStatusEvent) || !event.connection || !this._roomCreator) return; + + const statuses = event.getParser().statuses; + + if(!statuses || !statuses.length) return; + + const roomInstance = this._roomCreator.getRoomInstance(this._currentRoomId); + + if(!roomInstance) return; + + const zScale = (roomInstance.model.getValue(RoomVariableEnum.ROOM_Z_SCALE) || 1); + + for(const status of statuses) + { + if(!status) continue; + + let height = status.height; + + if(height) height = (height / zScale); + + const location = new Vector3d(status.x, status.y, (status.z + height)); + const direction = new Vector3d(status.direction); + + let goal: IVector3D = null; + + if(status.didMove) goal = new Vector3d(status.targetX, status.targetY, status.targetZ); + + this._roomCreator.updateRoomObjectUserLocation(this._currentRoomId, status.id, location, goal, status.canStandUp, height, direction, status.headDirection); + this._roomCreator.updateRoomObjectUserFlatControl(this._currentRoomId, status.id, null); + + let isPosture = true; + let postureUpdate = false; + let postureType = RoomObjectVariable.STD; + let parameter = ''; + + if(status.actions && status.actions.length) + { + for(const action of status.actions) + { + if(!action) continue; + + switch(action.action) + { + case 'flatctrl': + this._roomCreator.updateRoomObjectUserFlatControl(this._currentRoomId, status.id, action.value); + break; + case 'sign': + if(status.actions.length === 1) isPosture = false; + + this._roomCreator.updateRoomObjectUserAction(this._currentRoomId, status.id, RoomObjectVariable.FIGURE_SIGN, parseInt(action.value)); + break; + case 'gst': + if(status.actions.length === 1) isPosture = false; + + this._roomCreator.updateRoomObjectUserPetGesture(this._currentRoomId, status.id, action.value); + break; + case 'wav': + case 'mv': + postureUpdate = true; + postureType = action.action; + parameter = action.value; + break; + case 'trd': break; + default: + postureUpdate = true; + postureType = action.action; + parameter = action.value; + break; + } + } + } + + if(postureUpdate) this._roomCreator.updateRoomObjectUserPosture(this._currentRoomId, status.id, postureType, parameter); + else if(isPosture) this._roomCreator.updateRoomObjectUserPosture(this._currentRoomId, status.id, RoomObjectVariable.STD, ''); + } + } + + private onRoomUnitChatEvent(event: RoomUnitChatEvent): void + { + if(!event.connection || !this._roomCreator) return; + + const parser = event.getParser(); + + if(!parser) return; + + this._roomCreator.updateRoomObjectUserGesture(this._currentRoomId, parser.roomIndex, parser.gesture); + this._roomCreator.updateRoomObjectUserAction(this._currentRoomId, parser.roomIndex, RoomObjectVariable.FIGURE_TALK, (parser.message.length / 10)); + } + + private onRoomUnitTypingEvent(event: RoomUnitTypingEvent): void + { + if(!(event instanceof RoomUnitTypingEvent) || !event.connection || !this._roomCreator) return; + + this._roomCreator.updateRoomObjectUserAction(this._currentRoomId, event.getParser().unitId, RoomObjectVariable.FIGURE_IS_TYPING, event.getParser().isTyping ? 1 : 0); + } + + private onPetFigureUpdateEvent(event: PetFigureUpdateEvent): void + { + if(!(event instanceof PetFigureUpdateEvent) || !event.connection || !this._roomCreator) return; + + const parser = event.getParser(); + + if(!parser) return; + + this._roomCreator.updateRoomObjectUserFigure(this._currentRoomId, parser.roomIndex, parser.figureData.figuredata, '' , '', parser.isRiding); + } + + private onYouArePlayingGameEvent(event: YouArePlayingGameEvent): void + { + if(!event) return; + + const parser = event.getParser(); + + if(!parser) return; + + this._roomCreator.setRoomEngineGameMode(this._currentRoomId, parser.isPlaying); + } + + private addRoomObjectFurnitureFloor(roomId: number, data: FurnitureFloorDataParser): void + { + if(!data || !this._roomCreator) return; + + const location = new Vector3d(data.x, data.y, data.z); + const direction = new Vector3d(data.direction); + + if(data.spriteName) + { + this._roomCreator.addFurnitureFloorByTypeName(roomId, data.itemId, data.spriteName, location, direction, data.state, data.data, data.extra, data.expires, data.usagePolicy, data.userId, data.username, true, true, data.stackHeight); + } + else + { + this._roomCreator.addFurnitureFloor(roomId, data.itemId, data.spriteId, location, direction, data.state, data.data, data.extra, data.expires, data.usagePolicy, data.userId, data.username, true, true, data.stackHeight); + } + } + + private addRoomObjectFurnitureWall(roomId: number, data: FurnitureWallDataParser): void + { + if(!data || !this._roomCreator) return; + + const wallGeometry = this._roomCreator.getLegacyWallGeometry(roomId); + + if(!wallGeometry) return; + + let location: IVector3D = null; + + if(!data._Str_22379) + { + location = wallGeometry.getLocation(data.width, data.height, data.localX, data.localY, data.direction); + } + else + { + //location = wallGeometry._Str_24084(data.y, data.z, data.direction); + } + + const direction = new Vector3d(wallGeometry.getDirection(data.direction)); + + this._roomCreator.addFurnitureWall(roomId, data.itemId, data.spriteId, location, direction, data.state, data.stuffData, data.secondsToExpiration, data.usagePolicy, data.userId, data.username); + } + + private onIgnoreResultEvent(event: IgnoreResultEvent): void + { + if(!event) return; + + const parser = event.getParser(); + + if(!parser) return; + + const roomSession = this._roomCreator.roomSessionManager.getSession(this._currentRoomId); + + if(!roomSession) return; + + const userData = roomSession.userDataManager.getUserDataByName(parser.name); + + if(!userData) return; + + switch(parser.result) + { + case 1: + case 2: + this._roomCreator.updateRoomObjectUserAction(this._currentRoomId, userData.roomIndex, RoomObjectVariable.FIGURE_IS_MUTED, 1); + return; + case 3: + this._roomCreator.updateRoomObjectUserAction(this._currentRoomId, userData.roomIndex, RoomObjectVariable.FIGURE_IS_MUTED, 0); + return; + } + } + + // public _SafeStr_10580(event:_SafeStr_2242): void + // { + // var arrayIndex:int; + // var discoColours:Array; + // var discoTimer:Timer; + // var eventParser:_SafeStr_4576 = (event.parser as _SafeStr_4576); + // switch (eventParser._SafeStr_7025) + // { + // case 0: + // _SafeStr_4588.init(250, 5000); + // _SafeStr_4588._SafeStr_6766(); + // return; + // case 1: + // _SafeStr_4231.init(250, 5000); + // _SafeStr_4231._SafeStr_6766(); + // return; + // case 2: + // this._SafeStr_10592.roomSessionManager.events.dispatchEvent(new _SafeStr_2821(this._SafeStr_10593, -1, true)); + // return; + // case 3: + // arrayIndex = 0; + // discoColours = [29371, 16731195, 16764980, 0x99FF00, 29371, 16731195, 16764980, 0x99FF00, 0]; + // discoTimer = new Timer(1000, (discoColours.length + 1)); + // discoTimer.addEventListener(TimerEvent.TIMER, function (k:TimerEvent): void + // { + // if (arrayIndex == discoColours.length) + // { + // _SafeStr_10592._SafeStr_21164(_SafeStr_10593, discoColours[arrayIndex++], 176, true); + // } else + // { + // _SafeStr_10592._SafeStr_21164(_SafeStr_10593, discoColours[arrayIndex++], 176, false); + // }; + // }); + // discoTimer.start(); + // return; + // }; + // } + + public get currentRoomId(): number + { + return this._currentRoomId; + } +} diff --git a/src/nitro/room/RoomObjectEventHandler.ts b/src/nitro/room/RoomObjectEventHandler.ts new file mode 100644 index 00000000..58a20147 --- /dev/null +++ b/src/nitro/room/RoomObjectEventHandler.ts @@ -0,0 +1,2055 @@ +import { Disposable } from '../../core/common/disposable/Disposable'; +import { NitroLogger } from '../../core/common/logger/NitroLogger'; +import { RoomObjectEvent } from '../../room/events/RoomObjectEvent'; +import { RoomObjectMouseEvent } from '../../room/events/RoomObjectMouseEvent'; +import { RoomSpriteMouseEvent } from '../../room/events/RoomSpriteMouseEvent'; +import { RoomObjectUpdateMessage } from '../../room/messages/RoomObjectUpdateMessage'; +import { IRoomObject } from '../../room/object/IRoomObject'; +import { IRoomObjectController } from '../../room/object/IRoomObjectController'; +import { IRoomCanvasMouseListener } from '../../room/renderer/IRoomCanvasMouseListener'; +import { IRoomGeometry } from '../../room/utils/IRoomGeometry'; +import { IVector3D } from '../../room/utils/IVector3D'; +import { RoomEnterEffect } from '../../room/utils/RoomEnterEffect'; +import { Vector3d } from '../../room/utils/Vector3d'; +import { BotPlaceComposer } from '../communication/messages/outgoing/room/engine/BotPlaceComposer'; +import { GetItemDataComposer } from '../communication/messages/outgoing/room/engine/GetItemDataComposer'; +import { ModifyWallItemDataComposer } from '../communication/messages/outgoing/room/engine/ModifyWallItemDataComposer'; +import { PetMoveComposer } from '../communication/messages/outgoing/room/engine/PetMoveComposer'; +import { PetPlaceComposer } from '../communication/messages/outgoing/room/engine/PetPlaceComposer'; +import { RemoveWallItemComposer } from '../communication/messages/outgoing/room/engine/RemoveWallItemComposer'; +import { FurnitureFloorUpdateComposer } from '../communication/messages/outgoing/room/furniture/floor/FurnitureFloorUpdateComposer'; +import { FurniturePickupComposer } from '../communication/messages/outgoing/room/furniture/FurniturePickupComposer'; +import { FurniturePlaceComposer } from '../communication/messages/outgoing/room/furniture/FurniturePlaceComposer'; +import { FurniturePostItPlaceComposer } from '../communication/messages/outgoing/room/furniture/FurniturePostItPlaceComposer'; +import { FurnitureColorWheelComposer } from '../communication/messages/outgoing/room/furniture/logic/FurnitureColorWheelComposer'; +import { FurnitureDiceActivateComposer } from '../communication/messages/outgoing/room/furniture/logic/FurnitureDiceActivateComposer'; +import { FurnitureDiceDeactivateComposer } from '../communication/messages/outgoing/room/furniture/logic/FurnitureDiceDeactivateComposer'; +import { FurnitureMultiStateComposer } from '../communication/messages/outgoing/room/furniture/logic/FurnitureMultiStateComposer'; +import { FurnitureOneWayDoorComposer } from '../communication/messages/outgoing/room/furniture/logic/FurnitureOneWayDoorComposer'; +import { FurnitureRandomStateComposer } from '../communication/messages/outgoing/room/furniture/logic/FurnitureRandomStateComposer'; +import { FurnitureWallMultiStateComposer } from '../communication/messages/outgoing/room/furniture/logic/FurnitureWallMultiStateComposer'; +import { FurnitureWallUpdateComposer } from '../communication/messages/outgoing/room/furniture/wall/FurnitureWallUpdateComposer'; +import { RoomUnitLookComposer } from '../communication/messages/outgoing/room/unit/RoomUnitLookComposer'; +import { RoomUnitWalkComposer } from '../communication/messages/outgoing/room/unit/RoomUnitWalkComposer'; +import { Nitro } from '../Nitro'; +import { MouseEventType } from '../ui/MouseEventType'; +import { RoomObjectPlacementSource } from './enums/RoomObjectPlacementSource'; +import { RoomEngineDimmerStateEvent } from './events/RoomEngineDimmerStateEvent'; +import { RoomEngineObjectEvent } from './events/RoomEngineObjectEvent'; +import { RoomEngineObjectPlacedEvent } from './events/RoomEngineObjectPlacedEvent'; +import { RoomEngineObjectPlacedOnUserEvent } from './events/RoomEngineObjectPlacedOnUserEvent'; +import { RoomEngineSamplePlaybackEvent } from './events/RoomEngineSamplePlaybackEvent'; +import { RoomEngineTriggerWidgetEvent } from './events/RoomEngineTriggerWidgetEvent'; +import { RoomObjectBadgeAssetEvent } from './events/RoomObjectBadgeAssetEvent'; +import { RoomObjectDataRequestEvent } from './events/RoomObjectDataRequestEvent'; +import { RoomObjectDimmerStateUpdateEvent } from './events/RoomObjectDimmerStateUpdateEvent'; +import { RoomObjectFloorHoleEvent } from './events/RoomObjectFloorHoleEvent'; +import { RoomObjectFurnitureActionEvent } from './events/RoomObjectFurnitureActionEvent'; +import { RoomObjectHSLColorEnabledEvent } from './events/RoomObjectHSLColorEnabledEvent'; +import { RoomObjectHSLColorEnableEvent } from './events/RoomObjectHSLColorEnableEvent'; +import { RoomObjectMoveEvent } from './events/RoomObjectMoveEvent'; +import { RoomObjectSamplePlaybackEvent } from './events/RoomObjectSamplePlaybackEvent'; +import { RoomObjectStateChangedEvent } from './events/RoomObjectStateChangedEvent'; +import { RoomObjectTileMouseEvent } from './events/RoomObjectTileMouseEvent'; +import { RoomObjectWallMouseEvent } from './events/RoomObjectWallMouseEvent'; +import { RoomObjectWidgetRequestEvent } from './events/RoomObjectWidgetRequestEvent'; +import { IRoomEngineServices } from './IRoomEngineServices'; +import { ObjectAvatarSelectedMessage } from './messages/ObjectAvatarSelectedMessage'; +import { ObjectDataUpdateMessage } from './messages/ObjectDataUpdateMessage'; +import { ObjectSelectedMessage } from './messages/ObjectSelectedMessage'; +import { ObjectTileCursorUpdateMessage } from './messages/ObjectTileCursorUpdateMessage'; +import { ObjectVisibilityUpdateMessage } from './messages/ObjectVisibilityUpdateMessage'; +import { IObjectData } from './object/data/IObjectData'; +import { RoomObjectCategory } from './object/RoomObjectCategory'; +import { RoomObjectOperationType } from './object/RoomObjectOperationType'; +import { RoomObjectType } from './object/RoomObjectType'; +import { RoomObjectUserType } from './object/RoomObjectUserType'; +import { RoomObjectVariable } from './object/RoomObjectVariable'; +import { FurnitureStackingHeightMap } from './utils/FurnitureStackingHeightMap'; +import { LegacyWallGeometry } from './utils/LegacyWallGeometry'; +import { SelectedRoomObjectData } from './utils/SelectedRoomObjectData'; + +export class RoomObjectEventHandler extends Disposable implements IRoomCanvasMouseListener +{ + private _roomEngine: IRoomEngineServices; + + private _eventIds: Map>; + + private _selectedAvatarId: number; + private _selectedObjectId: number; + private _selectedObjectCategory: number; + private _whereYouClickIsWhereYouGo: boolean; + private _objectPlacementSource: string; + + constructor(roomEngine: IRoomEngineServices) + { + super(); + + this._roomEngine = roomEngine; + + this._eventIds = new Map(); + + this._selectedAvatarId = -1; + this._selectedObjectId = -1; + this._selectedObjectCategory = -2; + this._whereYouClickIsWhereYouGo = true; + this._objectPlacementSource = null; + + this.onRoomEngineObjectEvent = this.onRoomEngineObjectEvent.bind(this); + + this._roomEngine.events.addEventListener(RoomEngineObjectEvent.ADDED, this.onRoomEngineObjectEvent); + } + + public dispose(): void + { + if(this._eventIds) + { + this._eventIds = null; + } + + this._roomEngine.events.removeEventListener(RoomEngineObjectEvent.ADDED, this.onRoomEngineObjectEvent); + + this._roomEngine = null; + } + + private onRoomEngineObjectEvent(event: RoomEngineObjectEvent): void + { + let selectedData = this.getSelectedRoomObjectData(event.roomId); + + if(!selectedData) return; + + if((selectedData.operation === RoomObjectOperationType.OBJECT_PLACE) && (selectedData.id === event.objectId)) + { + const roomObject = this._roomEngine.getRoomObject(event.roomId, selectedData.id, selectedData.category); + + if(roomObject && roomObject.model) + { + if(selectedData.category === RoomObjectCategory.FLOOR) + { + const allowedDirections = roomObject.model.getValue(RoomObjectVariable.FURNITURE_ALLOWED_DIRECTIONS); + + if(allowedDirections && allowedDirections.length) + { + const direction = new Vector3d(allowedDirections[0]); + + roomObject.setDirection(direction); + + this._Str_16022(event.roomId, selectedData.id, selectedData.category, selectedData.loc, direction, selectedData.operation, selectedData.typeId, selectedData._Str_4766, selectedData.stuffData, selectedData.state, selectedData._Str_15896, selectedData.posture); + + selectedData = this.getSelectedRoomObjectData(event.roomId); + + if(!selectedData) return; + } + } + } + + this.setFurnitureAlphaMultiplier(roomObject, 0.5); + } + } + + public _Str_20330(event: RoomSpriteMouseEvent, object: IRoomObject, geometry: IRoomGeometry): void + { + if(!event || !object) return; + + if(RoomEnterEffect.isRunning()) return; + + const type = object.type; + + let category = this._roomEngine.getRoomObjectCategoryForType(type); + + if((category !== RoomObjectCategory.ROOM) && (!this._roomEngine.isPlayingGame() || category !== RoomObjectCategory.UNIT)) category = RoomObjectCategory.MINIMUM; + + const _local_7 = this._Str_18648(category, event.type); + + if(_local_7 === event._Str_3463) + { + if((event.type === MouseEventType.MOUSE_CLICK) || (event.type === MouseEventType.DOUBLE_CLICK) || (event.type === MouseEventType.MOUSE_DOWN) || (event.type === MouseEventType.MOUSE_UP) || (event.type === MouseEventType.MOUSE_MOVE)) return; + } + else + { + if(event._Str_3463) + { + this._Str_11142(category, event.type, event._Str_3463); + } + } + + if(object.mouseHandler) object.mouseHandler.mouseEvent(event, geometry); + } + + public processRoomObjectPlacement(placementSource: string, roomId: number, id: number, category: number, typeId: number, extra: string = null, stuffData: IObjectData = null, state: number = -1, frameNumber: number = -1, posture: string = null): boolean + { + this._objectPlacementSource = placementSource; + + const location = new Vector3d(-100, -100); + const direction = new Vector3d(0); + + this.setSelectedRoomObjectData(roomId, id, category, location, direction, RoomObjectOperationType.OBJECT_PLACE, typeId, extra, stuffData, state, frameNumber, posture); + + if(this._roomEngine) + { + this._roomEngine._Str_16645(typeId, category, false, extra, stuffData, state, frameNumber, posture); + this._roomEngine._Str_7972(false); + } + + return true; + } + + public _Str_8675(k: number): boolean + { + this._Str_13199(k); + + return true; + } + + private _Str_18648(k: number, _arg_2: string): string + { + const existing = this._eventIds.get(k); + + if(!existing) return null; + + return (existing.get(_arg_2) || null); + } + + private _Str_11142(k: number, _arg_2: string, _arg_3: string): void + { + let existing = this._eventIds.get(k); + + if(!existing) + { + existing = new Map(); + + this._eventIds.set(k, existing); + } + + existing.delete(_arg_2); + existing.set(_arg_2, _arg_3); + } + + + public handleRoomObjectEvent(event: RoomObjectEvent, roomId: number): void + { + if(!event) return; + + if(event instanceof RoomObjectMouseEvent) + { + this.handleRoomObjectMouseEvent(event, roomId); + + return; + } + + switch(event.type) + { + case RoomObjectStateChangedEvent.STATE_CHANGE: + case RoomObjectStateChangedEvent.STATE_RANDOM: + this.onRoomObjectStateChangedEvent(event as RoomObjectStateChangedEvent, roomId); + return; + case RoomObjectDimmerStateUpdateEvent.DIMMER_STATE: + this.onRoomObjectDimmerStateUpdateEvent(event as RoomObjectDimmerStateUpdateEvent, roomId); + return; + case RoomObjectMoveEvent.POSITION_CHANGED: + case RoomObjectMoveEvent.OBJECT_REMOVED: + this.onRoomObjectMoveEvent(event as RoomObjectMoveEvent, roomId); + return; + case RoomObjectWidgetRequestEvent.OPEN_WIDGET: + case RoomObjectWidgetRequestEvent.CLOSE_WIDGET: + case RoomObjectWidgetRequestEvent.OPEN_FURNI_CONTEXT_MENU: + case RoomObjectWidgetRequestEvent.CLOSE_FURNI_CONTEXT_MENU: + case RoomObjectWidgetRequestEvent.PLACEHOLDER: + case RoomObjectWidgetRequestEvent.CREDITFURNI: + case RoomObjectWidgetRequestEvent.STICKIE: + case RoomObjectWidgetRequestEvent.PRESENT: + case RoomObjectWidgetRequestEvent.TROPHY: + case RoomObjectWidgetRequestEvent.TEASER: + case RoomObjectWidgetRequestEvent.ECOTRONBOX: + case RoomObjectWidgetRequestEvent.DIMMER: + case RoomObjectWidgetRequestEvent.WIDGET_REMOVE_DIMMER: + case RoomObjectWidgetRequestEvent.CLOTHING_CHANGE: + case RoomObjectWidgetRequestEvent.JUKEBOX_PLAYLIST_EDITOR: + case RoomObjectWidgetRequestEvent.MANNEQUIN: + case RoomObjectWidgetRequestEvent.PET_PRODUCT_MENU: + case RoomObjectWidgetRequestEvent.GUILD_FURNI_CONTEXT_MENU: + case RoomObjectWidgetRequestEvent.MONSTERPLANT_SEED_PLANT_CONFIRMATION_DIALOG: + case RoomObjectWidgetRequestEvent.PURCHASABLE_CLOTHING_CONFIRMATION_DIALOG: + case RoomObjectWidgetRequestEvent.BACKGROUND_COLOR: + case RoomObjectWidgetRequestEvent.MYSTERYBOX_OPEN_DIALOG: + case RoomObjectWidgetRequestEvent.EFFECTBOX_OPEN_DIALOG: + case RoomObjectWidgetRequestEvent.MYSTERYTROPHY_OPEN_DIALOG: + case RoomObjectWidgetRequestEvent.ACHIEVEMENT_RESOLUTION_OPEN: + case RoomObjectWidgetRequestEvent.ACHIEVEMENT_RESOLUTION_ENGRAVING: + case RoomObjectWidgetRequestEvent.ACHIEVEMENT_RESOLUTION_FAILED: + case RoomObjectWidgetRequestEvent.FRIEND_FURNITURE_CONFIRM: + case RoomObjectWidgetRequestEvent.FRIEND_FURNITURE_ENGRAVING: + case RoomObjectWidgetRequestEvent.BADGE_DISPLAY_ENGRAVING: + case RoomObjectWidgetRequestEvent.HIGH_SCORE_DISPLAY: + case RoomObjectWidgetRequestEvent.HIDE_HIGH_SCORE_DISPLAY: + case RoomObjectWidgetRequestEvent.INERNAL_LINK: + case RoomObjectWidgetRequestEvent.ROOM_LINK: + this.onRoomObjectWidgetRequestEvent(event as RoomObjectWidgetRequestEvent, roomId); + return; + case RoomObjectFurnitureActionEvent.DICE_ACTIVATE: + case RoomObjectFurnitureActionEvent.DICE_OFF: + case RoomObjectFurnitureActionEvent.USE_HABBOWHEEL: + case RoomObjectFurnitureActionEvent.STICKIE: + case RoomObjectFurnitureActionEvent.ENTER_ONEWAYDOOR: + this.onRoomObjectFurnitureActionEvent(event as RoomObjectFurnitureActionEvent, roomId); + return; + case RoomObjectFloorHoleEvent.ADD_HOLE: + case RoomObjectFloorHoleEvent.REMOVE_HOLE: + this.onRoomObjectFloorHoleEvent(event as RoomObjectFloorHoleEvent, roomId); + return; + case RoomObjectBadgeAssetEvent.LOAD_BADGE: + this.onRoomObjectBadgeAssetEvent(event as RoomObjectBadgeAssetEvent, roomId); + return; + case RoomObjectFurnitureActionEvent.MOUSE_ARROW: + case RoomObjectFurnitureActionEvent.MOUSE_BUTTON: + this.handleMousePointer(event as RoomObjectFurnitureActionEvent, roomId); + return; + case RoomObjectSamplePlaybackEvent.ROOM_OBJECT_INITIALIZED: + case RoomObjectSamplePlaybackEvent.ROOM_OBJECT_DISPOSED: + case RoomObjectSamplePlaybackEvent.PLAY_SAMPLE: + case RoomObjectSamplePlaybackEvent.CHANGE_PITCH: + this.handleRoomObjectSamplePlaybackEvent(event as RoomObjectSamplePlaybackEvent, roomId); + return; + case RoomObjectHSLColorEnableEvent.ROOM_BACKGROUND_COLOR: + this.onHSLColorEnableEvent(event as RoomObjectHSLColorEnableEvent, roomId); + return; + case RoomObjectDataRequestEvent.RODRE_CURRENT_USER_ID: + case RoomObjectDataRequestEvent.RODRE_URL_PREFIX: + this.onRoomObjectDataRequestEvent(event as RoomObjectDataRequestEvent, roomId); + return; + default: + NitroLogger.log(`Unhandled Event: ${ event.constructor.name }`, `Object ID: ${ event.object.id }`); + return; + } + } + + private handleRoomObjectMouseEvent(event: RoomObjectMouseEvent, roomId: number): void + { + if(!event || !event.type) return; + + switch(event.type) + { + case RoomObjectMouseEvent.CLICK: + this.handleRoomObjectMouseClickEvent(event, roomId); + return; + case RoomObjectMouseEvent.MOUSE_MOVE: + this.handleRoomObjectMouseMoveEvent(event, roomId); + return; + case RoomObjectMouseEvent.MOUSE_DOWN: + this.handleRoomObjectMouseDownEvent(event, roomId); + return; + case RoomObjectMouseEvent.MOUSE_ENTER: + this.handleRoomObjectMouseEnterEvent(event, roomId); + return; + case RoomObjectMouseEvent.MOUSE_LEAVE: + this.handleRoomObjectMouseLeaveEvent(event, roomId); + return; + } + } + + private handleRoomObjectMouseClickEvent(event: RoomObjectMouseEvent, roomId: number): void + { + if(!event) return; + + let operation = RoomObjectOperationType.OBJECT_UNDEFINED; + + const selectedData = this.getSelectedRoomObjectData(roomId); + + if(selectedData) operation = selectedData.operation; + + let didWalk = false; + let didMove = false; + + if(this._whereYouClickIsWhereYouGo) + { + if(!operation || (operation === RoomObjectOperationType.OBJECT_UNDEFINED)) + { + didWalk = this._Str_23423(roomId, event); + } + } + + const category = this._roomEngine.getRoomObjectCategoryForType(event.objectType); + + switch(operation) + { + case RoomObjectOperationType.OBJECT_MOVE: + if(category === RoomObjectCategory.ROOM) + { + if(selectedData) + { + this.processRoomObjectOperation(roomId, selectedData.id, selectedData.category, RoomObjectOperationType.OBJECT_MOVE_TO); + } + } + + else if(category === RoomObjectCategory.UNIT) + { + if(selectedData && (event.objectType === RoomObjectUserType.MONSTER_PLANT)) + { + this.processRoomObjectOperation(roomId, selectedData.id, selectedData.category, RoomObjectOperationType.OBJECT_MOVE_TO); + } + + if(!event.eventId) this._Str_11142(RoomObjectCategory.ROOM, MouseEventType.MOUSE_CLICK, event.eventId); + + this._Str_19253(roomId, event.objectId, category); + } + + didMove = true; + + if(event.objectId !== -1) this._Str_17481(roomId, event.objectId, category); + + break; + case RoomObjectOperationType.OBJECT_PLACE: + if(category === RoomObjectCategory.ROOM) + { + this._Str_19271(roomId, (event instanceof RoomObjectTileMouseEvent), (event instanceof RoomObjectWallMouseEvent)); + } + + else if(category === RoomObjectCategory.UNIT) + { + switch(event.objectType) + { + case RoomObjectUserType.MONSTER_PLANT: + case RoomObjectUserType.RENTABLE_BOT: + this._Str_19271(roomId, (event instanceof RoomObjectTileMouseEvent), (event instanceof RoomObjectWallMouseEvent)); + break; + default: + if(event.eventId) + { + this._Str_11142(RoomObjectCategory.ROOM, MouseEventType.MOUSE_CLICK, event.eventId); + } + + this._Str_19253(roomId, event.objectId, category); + break; + } + } + break; + case RoomObjectOperationType.OBJECT_UNDEFINED: + if(category === RoomObjectCategory.ROOM) + { + if(!didWalk && (event instanceof RoomObjectTileMouseEvent)) this.onRoomObjectTileMouseEvent(roomId, event); + } + else + { + this._Str_17481(roomId, event.objectId, category); + + didMove = false; + + if(category === RoomObjectCategory.UNIT) + { + if(event.ctrlKey && !event.altKey && !event.shiftKey && (event.objectType === RoomObjectUserType.RENTABLE_BOT)) + { + this.processRoomObjectOperation(roomId, event.objectId, category, RoomObjectOperationType.OBJECT_PICKUP_BOT); + } + + else if(event.ctrlKey && !event.altKey && !event.shiftKey && (event.objectType === RoomObjectUserType.MONSTER_PLANT)) + { + this.processRoomObjectOperation(roomId, event.objectId, category, RoomObjectOperationType.OBJECT_PICKUP_PET); + } + + else if(!event.ctrlKey && !event.altKey && event.shiftKey && (event.objectType === RoomObjectUserType.MONSTER_PLANT)) + { + this.processRoomObjectOperation(roomId, event.objectId, category, RoomObjectOperationType.OBJECT_ROTATE_POSITIVE); + } + + if(!this._roomEngine.isPlayingGame()) + { + didWalk = true; + } + else + { + didMove = true; + } + } + + else if((category === RoomObjectCategory.FLOOR) || (category === RoomObjectCategory.WALL)) + { + if(event.altKey || event.ctrlKey || event.shiftKey) + { + if(!event.ctrlKey && !event.altKey && event.shiftKey) + { + if(category === RoomObjectCategory.FLOOR) + { + if(this._roomEngine.events) + { + this._roomEngine.events.dispatchEvent(new RoomEngineObjectEvent(RoomEngineObjectEvent.REQUEST_ROTATE, roomId, event.objectId, category)); + } + } + } + + else if(event.ctrlKey && !event.altKey && !event.shiftKey) + { + this.processRoomObjectOperation(roomId, event.objectId, category, RoomObjectOperationType.OBJECT_PICKUP); + } + + if(!this._roomEngine.isPlayingGame()) + { + didWalk = true; + } + else + { + didMove = true; + } + } + } + + if(event.eventId) + { + if(didWalk) + { + this._Str_11142(RoomObjectCategory.ROOM, MouseEventType.MOUSE_CLICK, event.eventId); + } + + if(didMove) + { + this._Str_11142(RoomObjectCategory.MINIMUM, MouseEventType.MOUSE_CLICK, event.eventId); + } + } + } + break; + } + + if(category === RoomObjectCategory.ROOM) + { + const _local_15 = this._Str_18648(RoomObjectCategory.MINIMUM, MouseEventType.MOUSE_CLICK); + const _local_16 = this._Str_18648(RoomObjectCategory.UNIT, MouseEventType.MOUSE_CLICK); + + if((_local_15 !== event.eventId) && (_local_16 !== event.eventId) && !didMove) + { + this._Str_16209(roomId); + + if(this._roomEngine.events) this._roomEngine.events.dispatchEvent(new RoomEngineObjectEvent(RoomEngineObjectEvent.DESELECTED, roomId, -1, RoomObjectCategory.MINIMUM)); + + this._Str_12227(roomId, 0, false); + } + } + } + + private handleRoomObjectMouseMoveEvent(event: RoomObjectMouseEvent, roomId: number): void + { + if(!event) return; + + let operation = RoomObjectOperationType.OBJECT_UNDEFINED; + + const selectedData = this.getSelectedRoomObjectData(roomId); + + if(selectedData) operation = selectedData.operation; + + const category = this._roomEngine.getRoomObjectCategoryForType(event.objectType); + + if(this._roomEngine) + { + const roomCursor = this._roomEngine.getRoomObjectCursor(roomId); + + if(roomCursor && roomCursor.logic) + { + let newEvent: ObjectTileCursorUpdateMessage = null; + + if(event instanceof RoomObjectTileMouseEvent) + { + newEvent = this._Str_23824(event, roomId); + } + + else if(event.object && (event.object.id !== -1)) + { + if(this._whereYouClickIsWhereYouGo) + { + newEvent = this._Str_25124(category, roomId, event); + } + } + + else + { + newEvent = new ObjectTileCursorUpdateMessage(null, 0, false, event.eventId); + } + + roomCursor.processUpdateMessage(newEvent); + } + } + + switch(operation) + { + case RoomObjectOperationType.OBJECT_MOVE: + if(category === RoomObjectCategory.ROOM) this._Str_24048(event, roomId); + + return; + case RoomObjectOperationType.OBJECT_PLACE: + if(category === RoomObjectCategory.ROOM) this._Str_22548(event, roomId); + + return; + } + } + + private handleRoomObjectMouseDownEvent(event: RoomObjectMouseEvent, roomId: number): void + { + if(!event) return; + + let operation = RoomObjectOperationType.OBJECT_UNDEFINED; + + const selectedData = this.getSelectedRoomObjectData(roomId); + + if(selectedData) operation = selectedData.operation; + + const category = this._roomEngine.getRoomObjectCategoryForType(event.objectType); + + switch(operation) + { + case RoomObjectOperationType.OBJECT_UNDEFINED: + if((category === RoomObjectCategory.FLOOR) || (category === RoomObjectCategory.WALL) || (event.objectType === RoomObjectUserType.MONSTER_PLANT)) + { + if((event.altKey && !event.ctrlKey && !event.shiftKey) || this._Str_25211(event)) + { + if(this._roomEngine.events) this._roomEngine.events.dispatchEvent(new RoomEngineObjectEvent(RoomEngineObjectEvent.REQUEST_MOVE, roomId, event.objectId, category)); + } + } + return; + } + } + + private handleRoomObjectMouseEnterEvent(event: RoomObjectMouseEvent, roomId: number): void + { + const id = event.objectId; + const type = event.objectType; + const category = this._roomEngine.getRoomObjectCategoryForType(type); + + if(this._roomEngine.events) + { + this._roomEngine.events.dispatchEvent(new RoomEngineObjectEvent(RoomEngineObjectEvent.MOUSE_ENTER, roomId, id, category)); + } + } + + private handleRoomObjectMouseLeaveEvent(event: RoomObjectMouseEvent, roomId: number): void + { + const id = event.objectId; + const type = event.objectType; + const category = this._roomEngine.getRoomObjectCategoryForType(type); + + if(category !== RoomObjectCategory.ROOM) + { + if(category === RoomObjectCategory.UNIT) + { + const cursor = this._roomEngine.getRoomObjectCursor(roomId); + + if(cursor) cursor.processUpdateMessage(new ObjectDataUpdateMessage(0, null)); + } + } + + if(this._roomEngine.events) + { + this._roomEngine.events.dispatchEvent(new RoomEngineObjectEvent(RoomEngineObjectEvent.MOUSE_LEAVE, roomId, id, category)); + } + + return; + } + + private onRoomObjectStateChangedEvent(event: RoomObjectStateChangedEvent, roomId: number): void + { + if(!event) return; + + switch(event.type) + { + case RoomObjectStateChangedEvent.STATE_CHANGE: + this.updateRoomObjectState(roomId, event.object.id, event.object.type, event.state, false); + return; + case RoomObjectStateChangedEvent.STATE_RANDOM: + this.updateRoomObjectState(roomId, event.object.id, event.object.type, event.state, true); + return; + } + } + + private onRoomObjectDimmerStateUpdateEvent(event: RoomObjectDimmerStateUpdateEvent, roomId: number): void + { + if(!event) return; + + switch(event.type) + { + case RoomObjectDimmerStateUpdateEvent.DIMMER_STATE: + this._roomEngine.events.dispatchEvent(new RoomEngineDimmerStateEvent(roomId, event.state, event._Str_14686, event._Str_6815, event.color, event._Str_5123)); + return; + } + } + + private onRoomObjectMoveEvent(event: RoomObjectMoveEvent, roomId: number): void + { + if(!event || !this._roomEngine) return; + + switch(event.type) + { + case RoomObjectMoveEvent.POSITION_CHANGED: { + const objectId = event.objectId; + const objectType = event.objectType; + const objectCategory = this._roomEngine.getRoomObjectCategoryForType(objectType); + const object = this._roomEngine.getRoomObject(roomId, objectId, objectCategory); + const selectionArrow = this._roomEngine.getRoomObjectSelectionArrow(roomId); + + if(object && selectionArrow && selectionArrow.logic) + { + const location = object.getLocation(); + + selectionArrow.logic.processUpdateMessage(new RoomObjectUpdateMessage(location, null)); + } + return; + } + case RoomObjectMoveEvent.OBJECT_REMOVED: + this._Str_12227(roomId, 0, false); + return; + } + } + + private onRoomObjectWidgetRequestEvent(event: RoomObjectWidgetRequestEvent, roomId: number): void + { + if(!event || !this._roomEngine) return; + + const objectId = event.objectId; + const objectType = event.objectType; + const objectCategory = this._roomEngine.getRoomObjectCategoryForType(objectType); + const eventDispatcher = this._roomEngine.events; + + if(!eventDispatcher) return; + + switch(event.type) + { + case RoomObjectWidgetRequestEvent.OPEN_WIDGET: + eventDispatcher.dispatchEvent(new RoomEngineTriggerWidgetEvent(RoomEngineTriggerWidgetEvent.OPEN_WIDGET, roomId, objectId, objectCategory, ((event.object as IRoomObjectController).logic.widget))); + return; + case RoomObjectWidgetRequestEvent.CLOSE_WIDGET: + eventDispatcher.dispatchEvent(new RoomEngineTriggerWidgetEvent(RoomEngineTriggerWidgetEvent.CLOSE_WIDGET, roomId, objectId, objectCategory, ((event.object as IRoomObjectController).logic.widget))); + return; + case RoomObjectWidgetRequestEvent.TROPHY: + eventDispatcher.dispatchEvent(new RoomEngineTriggerWidgetEvent(RoomEngineTriggerWidgetEvent.REQUEST_TROPHY, roomId, objectId, objectCategory)); + return; + case RoomObjectWidgetRequestEvent.CREDITFURNI: + eventDispatcher.dispatchEvent(new RoomEngineTriggerWidgetEvent(RoomEngineTriggerWidgetEvent.REQUEST_CREDITFURNI, roomId, objectId, objectCategory)); + return; + case RoomObjectWidgetRequestEvent.INERNAL_LINK: + eventDispatcher.dispatchEvent(new RoomEngineTriggerWidgetEvent(RoomEngineTriggerWidgetEvent.REQUEST_INTERNAL_LINK, roomId, objectId, objectCategory)); + return; + case RoomObjectWidgetRequestEvent.ROOM_LINK: + eventDispatcher.dispatchEvent(new RoomEngineTriggerWidgetEvent(RoomEngineTriggerWidgetEvent.REQUEST_ROOM_LINK, roomId, objectId, objectCategory)); + return; + case RoomObjectWidgetRequestEvent.HIGH_SCORE_DISPLAY: + eventDispatcher.dispatchEvent(new RoomEngineTriggerWidgetEvent(RoomEngineTriggerWidgetEvent.REQUEST_HIGH_SCORE_DISPLAY, roomId, objectId, objectCategory)); + return; + case RoomObjectWidgetRequestEvent.HIDE_HIGH_SCORE_DISPLAY: + eventDispatcher.dispatchEvent(new RoomEngineTriggerWidgetEvent(RoomEngineTriggerWidgetEvent.REQUEST_HIDE_HIGH_SCORE_DISPLAY, roomId, objectId, objectCategory)); + return; + case RoomObjectWidgetRequestEvent.STICKIE: + eventDispatcher.dispatchEvent(new RoomEngineTriggerWidgetEvent(RoomEngineTriggerWidgetEvent.REQUEST_STICKIE, roomId, objectId, objectCategory)); + return; + case RoomObjectWidgetRequestEvent.DIMMER: + eventDispatcher.dispatchEvent(new RoomEngineTriggerWidgetEvent(RoomEngineTriggerWidgetEvent.REQUEST_DIMMER, roomId, objectId, objectCategory)); + return; + case RoomObjectWidgetRequestEvent.PURCHASABLE_CLOTHING_CONFIRMATION_DIALOG: + eventDispatcher.dispatchEvent(new RoomEngineTriggerWidgetEvent(RoomEngineTriggerWidgetEvent.REQUEST_PURCHASABLE_CLOTHING_CONFIRMATION_DIALOG, roomId, objectId, objectCategory)); + break; + case RoomObjectWidgetRequestEvent.MYSTERYBOX_OPEN_DIALOG: + eventDispatcher.dispatchEvent(new RoomEngineTriggerWidgetEvent(RoomEngineTriggerWidgetEvent.REQUEST_MYSTERYBOX_OPEN_DIALOG, roomId, objectId, objectCategory)); + break; + case RoomObjectWidgetRequestEvent.MYSTERYTROPHY_OPEN_DIALOG: + eventDispatcher.dispatchEvent(new RoomEngineTriggerWidgetEvent(RoomEngineTriggerWidgetEvent.REQUEST_MYSTERYTROPHY_OPEN_DIALOG, roomId, objectId, objectCategory)); + break; + case RoomObjectWidgetRequestEvent.EFFECTBOX_OPEN_DIALOG: + eventDispatcher.dispatchEvent(new RoomEngineTriggerWidgetEvent(RoomEngineTriggerWidgetEvent.REQUEST_EFFECTBOX_OPEN_DIALOG, roomId, objectId, objectCategory)); + break; + case RoomObjectWidgetRequestEvent.MONSTERPLANT_SEED_PLANT_CONFIRMATION_DIALOG: + eventDispatcher.dispatchEvent(new RoomEngineTriggerWidgetEvent(RoomEngineTriggerWidgetEvent.REQUEST_MONSTERPLANT_SEED_PLANT_CONFIRMATION_DIALOG, roomId, objectId, objectCategory)); + break; + case RoomObjectWidgetRequestEvent.MANNEQUIN: + eventDispatcher.dispatchEvent(new RoomEngineTriggerWidgetEvent(RoomEngineTriggerWidgetEvent.REQUEST_MANNEQUIN, roomId, objectId, objectCategory)); + break; + + case RoomObjectWidgetRequestEvent.BACKGROUND_COLOR: + eventDispatcher.dispatchEvent(new RoomEngineTriggerWidgetEvent(RoomEngineTriggerWidgetEvent.REQUEST_BACKGROUND_COLOR, roomId, objectId, objectCategory)); + break; + case RoomObjectWidgetRequestEvent.FRIEND_FURNITURE_ENGRAVING: + eventDispatcher.dispatchEvent(new RoomEngineTriggerWidgetEvent(RoomEngineTriggerWidgetEvent.REQUEST_FRIEND_FURNITURE_ENGRAVING, roomId, objectId, objectCategory)); + break; + case RoomObjectWidgetRequestEvent.PRESENT: + eventDispatcher.dispatchEvent(new RoomEngineTriggerWidgetEvent(RoomEngineTriggerWidgetEvent.REQUEST_PRESENT, roomId, objectId, objectCategory)); + break; + + + } + } + + private onRoomObjectFurnitureActionEvent(event: RoomObjectFurnitureActionEvent, roomId: number): void + { + if(!event) return; + + this.useObject(roomId, event.object.id, event.object.type, event.type); + } + + private onRoomObjectFloorHoleEvent(event: RoomObjectFloorHoleEvent, roomId: number): void + { + if(!event) return; + + switch(event.type) + { + case RoomObjectFloorHoleEvent.ADD_HOLE: + this._roomEngine.addRoomInstanceFloorHole(roomId, event.objectId); + return; + case RoomObjectFloorHoleEvent.REMOVE_HOLE: + this._roomEngine.removeRoomInstanceFloorHole(roomId, event.objectId); + return; + } + } + + private onRoomObjectBadgeAssetEvent(event: RoomObjectBadgeAssetEvent, roomId: number): void + { + if(!event || !this._roomEngine) return; + + switch(event.type) + { + case RoomObjectBadgeAssetEvent.LOAD_BADGE: { + const objectId = event.objectId; + const objectType = event.objectType; + const objectCategory = this._roomEngine.getRoomObjectCategoryForType(objectType); + + this._roomEngine.loadRoomObjectBadgeImage(roomId, objectId, objectCategory, event.badgeId, event.groupBadge); + return; + } + } + } + + private handleMousePointer(event: RoomObjectFurnitureActionEvent, roomId: number): void + { + if(!event) return; + + this._roomEngine.updateMousePointer(event.type, event.objectId, event.objectType); + } + + private handleRoomObjectSamplePlaybackEvent(event: RoomObjectSamplePlaybackEvent, roomId: number): void + { + if(!event) return; + + const objectCategory = this._roomEngine.getRoomObjectCategoryForType(event.objectType); + + switch(event.type) + { + case RoomObjectSamplePlaybackEvent.ROOM_OBJECT_INITIALIZED: + this._roomEngine.events.dispatchEvent(new RoomEngineSamplePlaybackEvent(RoomEngineSamplePlaybackEvent.ROOM_OBJECT_INITIALIZED, roomId, event.objectId, objectCategory, event.sampleId, event.pitch)); + break; + case RoomObjectSamplePlaybackEvent.ROOM_OBJECT_DISPOSED: + this._roomEngine.events.dispatchEvent(new RoomEngineSamplePlaybackEvent(RoomEngineSamplePlaybackEvent.ROOM_OBJECT_DISPOSED, roomId, event.objectId, objectCategory, event.sampleId, event.pitch)); + break; + case RoomObjectSamplePlaybackEvent.PLAY_SAMPLE: + this._roomEngine.events.dispatchEvent(new RoomEngineSamplePlaybackEvent(RoomEngineSamplePlaybackEvent.PLAY_SAMPLE, roomId, event.objectId, objectCategory, event.sampleId, event.pitch)); + break; + case RoomObjectSamplePlaybackEvent.CHANGE_PITCH: + this._roomEngine.events.dispatchEvent(new RoomEngineSamplePlaybackEvent(RoomEngineSamplePlaybackEvent.CHANGE_PITCH, roomId, event.objectId, objectCategory, event.sampleId, event.pitch)); + break; + } + } + + private onHSLColorEnableEvent(event: RoomObjectHSLColorEnableEvent, roomId: number): void + { + if(!event || !this._roomEngine) return; + + switch(event.type) + { + case RoomObjectHSLColorEnableEvent.ROOM_BACKGROUND_COLOR: + this._roomEngine.events.dispatchEvent(new RoomObjectHSLColorEnabledEvent(RoomObjectHSLColorEnabledEvent.ROOM_BACKGROUND_COLOR, roomId, event.enable, event.hue, event.saturation, event.lightness)); + return; + } + } + + private onRoomObjectDataRequestEvent(event: RoomObjectDataRequestEvent, roomId: number): void + { + if(!event || !this._roomEngine || !event.object) return; + + switch(event.type) + { + case RoomObjectDataRequestEvent.RODRE_CURRENT_USER_ID: + event.object.model.setValue(RoomObjectVariable.SESSION_CURRENT_USER_ID, this._roomEngine.sessionDataManager.userId); + return; + case RoomObjectDataRequestEvent.RODRE_URL_PREFIX: + event.object.model.setValue(RoomObjectVariable.SESSION_CURRENT_USER_ID, Nitro.instance.getConfiguration('url.prefix')); + return; + } + } + + private onRoomObjectTileMouseEvent(roomId: number, event: RoomObjectTileMouseEvent): void + { + if(!this._roomEngine || this._roomEngine.isDecorating || !this._roomEngine.roomSessionManager) return; + + const session = this._roomEngine.roomSessionManager.getSession(roomId); + + if(!session || session.isSpectator) return; + + this.sendWalkUpdate(event._Str_16836, event._Str_17676); + } + + private _Str_24048(event: RoomObjectMouseEvent, roomId: number): void + { + if(!event || !this._roomEngine) return; + + const eventDispatcher = this._roomEngine.events; + + if(!eventDispatcher) return; + + const selectedData = this.getSelectedRoomObjectData(roomId); + + if(!selectedData) return; + + const roomObject = this._roomEngine.getRoomObject(roomId, selectedData.id, selectedData.category); + + if(!roomObject) return; + + let _local_6 = true; + + if((selectedData.category === RoomObjectCategory.FLOOR) || (selectedData.category === RoomObjectCategory.UNIT)) + { + const stackingHeightMap = this._roomEngine.getFurnitureStackingHeightMap(roomId); + + if(!(((event instanceof RoomObjectTileMouseEvent)) && (this._Str_18155(roomObject, selectedData, Math.trunc(event.tileX + 0.5), Math.trunc(event.tileY + 0.5), stackingHeightMap)))) + { + this._Str_18155(roomObject, selectedData, selectedData.loc.x, selectedData.loc.y, stackingHeightMap); + + _local_6 = false; + } + } + + else if((selectedData.category === RoomObjectCategory.WALL)) + { + _local_6 = false; + + if(event instanceof RoomObjectWallMouseEvent) + { + const _local_10 = event.wallLocation; + const _local_11 = event.wallWidth; + const _local_12 = event.wallHeight; + const _local_13 = event.x; + const _local_14 = event.y; + const _local_15 = event.direction; + + if(this._Str_22090(roomObject, selectedData, _local_10, _local_11, _local_12, _local_13, _local_14, _local_15)) + { + _local_6 = true; + } + } + + if(!_local_6) + { + roomObject.setLocation(selectedData.loc); + roomObject.setDirection(selectedData.dir); + } + + this._roomEngine.updateRoomObjectMask(roomId, selectedData.id, _local_6); + } + + if(_local_6) + { + this.setFurnitureAlphaMultiplier(roomObject, 0.5); + + this._roomEngine._Str_7972(false); + } + else + { + this.setFurnitureAlphaMultiplier(roomObject, 0); + + this._roomEngine._Str_7972(true); + } + } + + private _Str_22548(event: RoomObjectMouseEvent, roomId: number): void + { + if(!event || !this._roomEngine) return; + + const eventDispatcher = this._roomEngine.events; + + if(!eventDispatcher) return; + + let selectedData = this.getSelectedRoomObjectData(roomId); + + if(!selectedData) return; + + let roomObject = this._roomEngine.getRoomObject(roomId, selectedData.id, selectedData.category); + + if(!roomObject) + { + if(event instanceof RoomObjectTileMouseEvent) + { + if(selectedData.category === RoomObjectCategory.FLOOR) + { + this._roomEngine.addFurnitureFloor(roomId, selectedData.id, selectedData.typeId, selectedData.loc, selectedData.dir, 0, selectedData.stuffData, parseFloat(selectedData._Str_4766), -1, 0, 0, '', false); + } + + else if(selectedData.category === RoomObjectCategory.UNIT) + { + this._roomEngine.addRoomObjectUser(roomId, selectedData.id, new Vector3d(), new Vector3d(180), 180, selectedData.typeId, selectedData._Str_4766); + + const roomObject = this._roomEngine.getRoomObject(roomId, selectedData.id, selectedData.category); + + (roomObject && selectedData.posture && roomObject.model.setValue(RoomObjectVariable.FIGURE_POSTURE, selectedData.posture)); + } + } + + else if(event instanceof RoomObjectWallMouseEvent) + { + if(selectedData.category === RoomObjectCategory.WALL) + { + this._roomEngine.addFurnitureWall(roomId, selectedData.id, selectedData.typeId, selectedData.loc, selectedData.dir, 0, selectedData._Str_4766, 0); + } + } + + roomObject = this._roomEngine.getRoomObject(roomId, selectedData.id, selectedData.category); + + if(roomObject) + { + if(selectedData.category === RoomObjectCategory.FLOOR) + { + const allowedDirections = roomObject.model.getValue(RoomObjectVariable.FURNITURE_ALLOWED_DIRECTIONS); + + if(allowedDirections && allowedDirections.length) + { + const direction = new Vector3d(allowedDirections[0]); + + roomObject.setDirection(direction); + + this._Str_16022(roomId, selectedData.id, selectedData.category, selectedData.loc, direction, selectedData.operation, selectedData.typeId, selectedData._Str_4766, selectedData.stuffData, selectedData.state, selectedData._Str_15896, selectedData.posture); + + selectedData = this.getSelectedRoomObjectData(roomId); + + if(!selectedData) return; + } + } + } + + this.setFurnitureAlphaMultiplier(roomObject, 0.5); + this._roomEngine._Str_7972(true); + } + + if(roomObject) + { + let _local_12 = true; + + const stackingHeightMap = this._roomEngine.getFurnitureStackingHeightMap(roomId); + + if(selectedData.category === RoomObjectCategory.FLOOR) + { + if(!((event instanceof RoomObjectTileMouseEvent) && this._Str_18155(roomObject, selectedData, Math.trunc(event.tileX + 0.5), Math.trunc(event.tileY + 0.5), stackingHeightMap))) + { + this._roomEngine.removeRoomObjectFloor(roomId, selectedData.id); + + _local_12 = false; + } + } + + else if(selectedData.category === RoomObjectCategory.WALL) + { + _local_12 = false; + + if(event instanceof RoomObjectWallMouseEvent) + { + const _local_14 = event.wallLocation; + const _local_15 = event.wallWidth; + const _local_16 = event.wallHeight; + const _local_17 = event.x; + const _local_18 = event.y; + const _local_19 = event.direction; + + if(this._Str_22090(roomObject, selectedData, _local_14, _local_15, _local_16, _local_17, _local_18, _local_19)) + { + _local_12 = true; + } + } + + if(!_local_12) + { + this._roomEngine.removeRoomObjectWall(roomId, selectedData.id); + } + + this._roomEngine.updateRoomObjectMask(roomId, selectedData.id, _local_12); + } + + else if(selectedData.category === RoomObjectCategory.UNIT) + { + if(!((event instanceof RoomObjectTileMouseEvent) && this._Str_25586(roomObject, Math.trunc(event.tileX + 0.5), Math.trunc(event.tileY + 0.5), this._roomEngine.getLegacyWallGeometry(roomId)))) + { + this._roomEngine.removeRoomObjectUser(roomId, selectedData.id); + + _local_12 = false; + } + } + + this._roomEngine._Str_7972(!_local_12); + } + } + + private _Str_18155(roomObject: IRoomObjectController, selectedObjectData: SelectedRoomObjectData, x: number, y: number, stackingHeightMap: FurnitureStackingHeightMap): boolean + { + if(!roomObject || !selectedObjectData) return false; + + const _local_6 = new Vector3d(); + _local_6.assign(roomObject.getDirection()); + + roomObject.setDirection(selectedObjectData.dir); + + const _local_7 = new Vector3d(x, y, 0); + const _local_8 = new Vector3d(); + + _local_8.assign(roomObject.getDirection()); + + let _local_9 = this._Str_21004(roomObject, _local_7, selectedObjectData.loc, selectedObjectData.dir, stackingHeightMap); + + if(!_local_9) + { + _local_8.x = this._Str_17555(roomObject, true); + + roomObject.setDirection(_local_8); + + _local_9 = this._Str_21004(roomObject, _local_7, selectedObjectData.loc, selectedObjectData.dir, stackingHeightMap); + } + + if(!_local_9) + { + roomObject.setDirection(_local_6); + + return false; + } + + roomObject.setLocation(_local_9); + + if(_local_8) roomObject.setDirection(_local_8); + + return true; + } + + private _Str_22090(k: IRoomObjectController, _arg_2: SelectedRoomObjectData, _arg_3: IVector3D, _arg_4: IVector3D, _arg_5: IVector3D, _arg_6: number, _arg_7: number, _arg_8: number): boolean + { + if(!k || !_arg_2) return false; + + const _local_9 = new Vector3d(_arg_8); + const _local_10 = this._Str_25568(k, _arg_3, _arg_4, _arg_5, _arg_6, _arg_7, _arg_2); + + if(!_local_10) return false; + + k.setLocation(_local_10); + k.setDirection(_local_9); + + return true; + } + + private _Str_21004(k: IRoomObject, _arg_2: IVector3D, _arg_3: IVector3D, _arg_4: IVector3D, _arg_5: FurnitureStackingHeightMap): Vector3d + { + if(!k || !k.model || !_arg_2) return null; + + let _local_15: Vector3d = null; + + const _local_6 = k.getDirection(); + + if(!_local_6) return null; + + if(!_arg_3 || !_arg_4) return null; + + if((_arg_2.x === _arg_3.x) && (_arg_2.y === _arg_3.y)) + { + if(_local_6.x === _arg_4.x) + { + _local_15 = new Vector3d(); + + _local_15.assign(_arg_3); + + return _local_15; + } + } + + let sizeX = k.model.getValue(RoomObjectVariable.FURNITURE_SIZE_X); + let sizeY = k.model.getValue(RoomObjectVariable.FURNITURE_SIZE_Y); + + if(sizeX < 1) sizeX = 1; + + if(sizeY < 1) sizeY = 1; + + const _local_9 = _arg_3.x; + const _local_10 = _arg_3.y; + let _local_11 = sizeX; + let _local_12 = sizeY; + let _local_13 = 0; + let _local_14 = (Math.trunc((Math.trunc(_local_6.x + 45) % 360) / 90)); + + if((_local_14 === 1) || (_local_14 === 3)) + { + _local_13 = sizeX; + + sizeX = sizeY; + sizeY = _local_13; + } + + _local_14 = Math.trunc((Math.trunc(_arg_4.x + 45) % 360) / 90); + + if((_local_14 === 1) || (_local_14 === 3)) + { + _local_13 = _local_11; + _local_11 = _local_12; + _local_12 = _local_13; + } + + if(_arg_5 && _arg_2) + { + const stackable = (k.model.getValue(RoomObjectVariable.FURNITURE_ALWAYS_STACKABLE) === 1); + + if(_arg_5.validateLocation(_arg_2.x, _arg_2.y, sizeX, sizeY, _local_9, _local_10, _local_11, _local_12, stackable)) + { + return new Vector3d(_arg_2.x, _arg_2.y, _arg_5.getTileHeight(_arg_2.x, _arg_2.y)); + } + + return null; + } + + return null; + } + + private _Str_25568(k: IRoomObject, _arg_2: IVector3D, _arg_3: IVector3D, _arg_4: IVector3D, _arg_5: number, _arg_6: number, _arg_7: SelectedRoomObjectData): Vector3d + { + if((((((k == null) || (k.model == null)) || (_arg_2 == null)) || (_arg_3 == null)) || (_arg_4 == null)) || (_arg_7 == null)) return null; + + const _local_8 = k.model.getValue(RoomObjectVariable.FURNITURE_SIZE_X); + const _local_9 = k.model.getValue(RoomObjectVariable.FURNITURE_SIZE_Z); + const _local_10 = k.model.getValue(RoomObjectVariable.FURNITURE_CENTER_Z); + + if((((_arg_5 < (_local_8 / 2)) || (_arg_5 > (_arg_3.length - (_local_8 / 2)))) || (_arg_6 < _local_10)) || (_arg_6 > (_arg_4.length - (_local_9 - _local_10)))) + { + if((_arg_5 < (_local_8 / 2)) && (_arg_5 <= (_arg_3.length - (_local_8 / 2)))) + { + _arg_5 = (_local_8 / 2); + } + else + { + if((_arg_5 >= (_local_8 / 2)) && (_arg_5 > (_arg_3.length - (_local_8 / 2)))) + { + _arg_5 = (_arg_3.length - (_local_8 / 2)); + } + } + + if((_arg_6 < _local_10) && (_arg_6 <= (_arg_4.length - (_local_9 - _local_10)))) + { + _arg_6 = _local_10; + } + else + { + if((_arg_6 >= _local_10) && (_arg_6 > (_arg_4.length - (_local_9 - _local_10)))) + { + _arg_6 = (_arg_4.length - (_local_9 - _local_10)); + } + } + } + + if((((_arg_5 < (_local_8 / 2)) || (_arg_5 > (_arg_3.length - (_local_8 / 2)))) || (_arg_6 < _local_10)) || (_arg_6 > (_arg_4.length - (_local_9 - _local_10)))) + { + return null; + } + + let _local_11 = Vector3d.sum(Vector3d.product(_arg_3, (_arg_5 / _arg_3.length)), Vector3d.product(_arg_4, (_arg_6 / _arg_4.length))); + + _local_11 = Vector3d.sum(_arg_2, _local_11); + + return _local_11; + } + + private updateRoomObjectState(roomId: number, objectId: number, type: string, state: number, isRandom: boolean): void + { + const category = this._roomEngine.getRoomObjectCategoryForType(type); + + this.sendStateUpdate(roomId, objectId, category, state, isRandom); + } + + private useObject(roomId: number, objectId: number, type: string, action: string): void + { + if(!this._roomEngine || !this._roomEngine.connection) return; + switch(action) + { + case RoomObjectFurnitureActionEvent.DICE_ACTIVATE: + this._roomEngine.connection.send(new FurnitureDiceActivateComposer(objectId)); + return; + case RoomObjectFurnitureActionEvent.DICE_OFF: + this._roomEngine.connection.send(new FurnitureDiceDeactivateComposer(objectId)); + return; + case RoomObjectFurnitureActionEvent.USE_HABBOWHEEL: + this._roomEngine.connection.send(new FurnitureColorWheelComposer(objectId)); + return; + case RoomObjectFurnitureActionEvent.STICKIE: + this._roomEngine.connection.send(new GetItemDataComposer(objectId)); + return; + case RoomObjectFurnitureActionEvent.ENTER_ONEWAYDOOR: + this._roomEngine.connection.send(new FurnitureOneWayDoorComposer(objectId)); + return; + } + } + + private sendStateUpdate(roomId: number, objectId: number, category: number, state: number, isRandom: boolean): boolean + { + if(!this._roomEngine || !this._roomEngine.connection) return true; + + if(category === RoomObjectCategory.FLOOR) + { + if(!isRandom) + { + this._roomEngine.connection.send(new FurnitureMultiStateComposer(objectId, state)); + } + else + { + this._roomEngine.connection.send(new FurnitureRandomStateComposer(objectId, state)); + } + } + + else if(category === RoomObjectCategory.WALL) + { + this._roomEngine.connection.send(new FurnitureWallMultiStateComposer(objectId, state)); + } + + return true; + } + + private sendWalkUpdate(x: number, y: number): void + { + if(!this._roomEngine || !this._roomEngine.connection) return; + + this._roomEngine.connection.send(new RoomUnitWalkComposer(x, y)); + } + + private _Str_25124(category: number, roomId: number, event: RoomObjectMouseEvent): ObjectTileCursorUpdateMessage + { + if(category !== RoomObjectCategory.FLOOR) return null; + + const roomObject = this._roomEngine.getRoomObject(roomId, event.objectId, RoomObjectCategory.FLOOR); + + if(!roomObject) return null; + + const location = this._Str_21925(roomObject, event); + + if(!location) return null; + + const furnitureHeightMap = this._roomEngine.getFurnitureStackingHeightMap(roomId); + + if(!furnitureHeightMap) return null; + + const x = location.x; + const y = location.y; + const z = location.z; + + return new ObjectTileCursorUpdateMessage(new Vector3d(x, y, roomObject.getLocation().z), z, true, event.eventId); + } + + private _Str_23423(k: number, _arg_2: RoomObjectMouseEvent): boolean + { + const _local_3 = this._roomEngine.getRoomObject(k, _arg_2.objectId, RoomObjectCategory.FLOOR); + const _local_4 = this._Str_21925(_local_3, _arg_2); + + if(_local_4) + { + this.sendWalkUpdate(_local_4.x, _local_4.y); + + return true; + } + + return false; + } + + private _Str_21925(k: IRoomObject, _arg_2: RoomObjectMouseEvent): Vector3d + { + if(!k || !_arg_2) return null; + + const furniData = this._roomEngine.sessionDataManager.getFloorItemDataByName(k.type); + + if(!furniData) return null; + + if(!furniData.canStandOn && !furniData.canSitOn && !furniData.canLayOn) return null; + + const model = k.model; + + if(!model) return null; + + const location = k.getLocation(); + const direction = k.getDirection(); + + let sizeX = model.getValue(RoomObjectVariable.FURNITURE_SIZE_X); + let sizeY = model.getValue(RoomObjectVariable.FURNITURE_SIZE_Y); + const sizeZ = model.getValue(RoomObjectVariable.FURNITURE_SIZE_Z); + + if((direction.x === 90) || (direction.x === 270)) [ sizeX, sizeY ] = [ sizeY, sizeX ]; + + if(sizeX < 1) sizeX = 1; + if(sizeY < 1) sizeY = 1; + + const renderingCanvas = this._roomEngine.getActiveRoomInstanceRenderingCanvas(); + + if(!renderingCanvas) return null; + + const scale = renderingCanvas.geometry.scale; + const _local_13 = furniData.canSitOn ? 0.5 : 0; + const _local_14 = ((((scale / 2) + _arg_2.spriteOffsetX) + _arg_2.localX) / (scale / 4)); + const _local_15 = (((_arg_2.spriteOffsetY + _arg_2.localY) + (((sizeZ - _local_13) * scale) / 2)) / (scale / 4)); + const _local_16 = ((_local_14 + (2 * _local_15)) / 4); + const _local_17 = ((_local_14 - (2 * _local_15)) / 4); + const _local_18 = Math.floor((location.x + _local_16)); + const _local_19 = Math.floor(((location.y - _local_17) + 1)); + + let _local_20 = false; + + if((_local_18 < location.x) || (_local_18 >= (location.x + sizeX))) _local_20 = true; + else if((_local_19 < location.y) || (_local_19 >= (location.y + sizeY))) _local_20 = true; + + const _local_21 = furniData.canSitOn ? (sizeZ - 0.5) : sizeZ; + + if(!_local_20) return new Vector3d(_local_18, _local_19, _local_21); + + return null; + } + + private _Str_23824(k: RoomObjectTileMouseEvent, roomId: number): ObjectTileCursorUpdateMessage + { + if(this._whereYouClickIsWhereYouGo) + { + return new ObjectTileCursorUpdateMessage(new Vector3d(k._Str_16836, k._Str_17676, k._Str_21459), 0, true, k.eventId); + } + + const roomObject = this._roomEngine.getRoomObjectCursor(roomId); + + if(roomObject && roomObject.visualization) + { + const _local_4 = k._Str_16836; + const _local_5 = k._Str_17676; + const _local_6 = k._Str_21459; + const _local_7 = this._roomEngine.getRoomInstance(roomId); + + if(_local_7) + { + const _local_8 = this._roomEngine.getRoomTileObjectMap(roomId); + + if(_local_8) + { + const _local_9 = _local_8._Str_19056(_local_4, _local_5); + const _local_10 = this._roomEngine.getFurnitureStackingHeightMap(roomId); + + if(_local_10) + { + if(_local_9 && _local_9.model && (_local_9.model.getValue(RoomObjectVariable.FURNITURE_IS_VARIABLE_HEIGHT) > 0)) + { + const _local_11 = _local_10.getTileHeight(_local_4, _local_5); + const _local_12 = this._roomEngine.getLegacyWallGeometry(roomId).getHeight(_local_4, _local_5); + + return new ObjectTileCursorUpdateMessage(new Vector3d(_local_4, _local_5, _local_6), (_local_11 - _local_12), true, k.eventId); + } + + return new ObjectTileCursorUpdateMessage(new Vector3d(_local_4, _local_5, _local_6), 0, true, k.eventId); + } + } + } + } + + return null; + } + + private _Str_19271(roomId: number, isTileEvent: boolean, isWallEvent: boolean): void + { + const selectedData = this.getSelectedRoomObjectData(roomId); + + if(!selectedData) return; + + let roomObject: IRoomObjectController = null; + let objectId = selectedData.id; + const category = selectedData.category; + + let x = 0; + let y = 0; + let z = 0; + let direction = 0; + let wallLocation = ''; + + if(this._roomEngine && this._roomEngine.connection) + { + roomObject = this._roomEngine.getRoomObject(roomId, objectId, category); + + if(roomObject) + { + const location = roomObject.getLocation(); + + direction = roomObject.getDirection().x; + + if((category === RoomObjectCategory.FLOOR) || (category === RoomObjectCategory.UNIT)) + { + x = location.x; + y = location.y; + z = location.z; + } + + else if(category === RoomObjectCategory.WALL) + { + x = location.x; + y = location.y; + z = location.z; + + const wallGeometry = this._roomEngine.getLegacyWallGeometry(roomId); + + if(wallGeometry) wallLocation = wallGeometry._Str_21860(location, direction); + } + + direction = ((((direction / 45) % 8) + 8) % 8); + + if((objectId < 0) && (category === RoomObjectCategory.UNIT)) objectId = (objectId * -1); + + if(this._objectPlacementSource !== RoomObjectPlacementSource.CATALOG) + { + if(category === RoomObjectCategory.UNIT) + { + if(selectedData.typeId === RoomObjectType.PET) + { + this._roomEngine.connection.send(new PetPlaceComposer(objectId, Math.trunc(x), Math.trunc(y))); + } + + else if(selectedData.typeId === RoomObjectType.RENTABLE_BOT) + { + this._roomEngine.connection.send(new BotPlaceComposer(objectId, Math.trunc(x), Math.trunc(y))); + } + } + + else if(roomObject.model.getValue(RoomObjectVariable.FURNITURE_IS_STICKIE) !== undefined) + { + this._roomEngine.connection.send(new FurniturePostItPlaceComposer(objectId, wallLocation)); + } + + else + { + this._roomEngine.connection.send(new FurniturePlaceComposer(objectId, category, wallLocation, Math.trunc(x), Math.trunc(y), direction)); + } + } + } + } + + this._roomEngine.setPlacedRoomObjectData(roomId, new SelectedRoomObjectData(selectedData.id, selectedData.category, null, selectedData.dir, null)); + + this._Str_13199(roomId); + + if(this._roomEngine && this._roomEngine.events) + { + const placedInRoom = (roomObject && (roomObject.id === selectedData.id)); + + this._roomEngine.events.dispatchEvent(new RoomEngineObjectPlacedEvent(RoomEngineObjectEvent.PLACED, roomId, objectId, category, wallLocation, x, y, z, direction, placedInRoom, isTileEvent, isWallEvent, selectedData._Str_4766)); + } + } + + public processRoomObjectWallOperation(roomId: number, objectId: number, category: number, operation: string, data: Map): boolean + { + if(!this._roomEngine) return false; + + const roomObject = this._roomEngine.getRoomObject(roomId, objectId, category); + + if(!roomObject) return false; + + switch(operation) + { + case RoomObjectOperationType.OBJECT_SAVE_STUFF_DATA: + if(this._roomEngine.connection) + { + //this._roomEngine.connection.send(new _Str_5686(objectId, data)); + } + break; + } + + return true; + } + + public processRoomObjectFloorOperation(roomId: number, objectId: number, operation: string, data: string): boolean + { + if(!this._roomEngine) return false; + + //this._roomEngine.connection.send(new _Str_10640(objectId, operation, data)); + + return true; + } + + public processRoomObjectOperation(roomId: number, objectId: number, category: number, operation: string): boolean + { + if(!this._roomEngine) return false; + + const roomObject = this._roomEngine.getRoomObject(roomId, objectId, category); + + if(!roomObject) return false; + + let _local_9 = true; + + switch(operation) + { + case RoomObjectOperationType.OBJECT_ROTATE_POSITIVE: + case RoomObjectOperationType.OBJECT_ROTATE_NEGATIVE: + if(this._roomEngine.connection) + { + let direction = 0; + + if(operation == RoomObjectOperationType.OBJECT_ROTATE_NEGATIVE) + { + direction = this._Str_17555(roomObject, false); + } + else + { + direction = this._Str_17555(roomObject, true); + } + + const x = roomObject.getLocation().x; + const y = roomObject.getLocation().y; + + if(this.isValidLocation(roomObject, new Vector3d(direction), this._roomEngine.getFurnitureStackingHeightMap(roomId))) + { + direction = Math.trunc((direction / 45)); + + if(roomObject.type === RoomObjectUserType.MONSTER_PLANT) + { + const roomSession = this._roomEngine.roomSessionManager.getSession(roomId); + + if(roomSession) + { + const userData = roomSession.userDataManager.getUserDataByIndex(objectId); + + if(userData) + { + this._roomEngine.connection.send(new PetMoveComposer(userData.webID, Math.trunc(x), Math.trunc(y), direction)); + } + } + } + else + { + this._roomEngine.connection.send(new FurnitureFloorUpdateComposer(objectId, x, y, direction)); + } + } + } + break; + case RoomObjectOperationType.OBJECT_EJECT: + case RoomObjectOperationType.OBJECT_PICKUP: + if(this._roomEngine.connection) this._roomEngine.connection.send(new FurniturePickupComposer(category, objectId)); + break; + case RoomObjectOperationType.OBJECT_PICKUP_PET: + if(this._roomEngine.connection) + { + const session = this._roomEngine.roomSessionManager.getSession(roomId); + + if(session) + { + const userData = session.userDataManager.getUserDataByIndex(objectId); + + session.pickupPet(userData.webID); + } + } + break; + case RoomObjectOperationType.OBJECT_PICKUP_BOT: + if(this._roomEngine.connection) + { + const session = this._roomEngine.roomSessionManager.getSession(roomId); + + if(session) + { + const userData = session.userDataManager.getUserDataByIndex(objectId); + + session.pickupBot(userData.webID); + } + } + break; + case RoomObjectOperationType.OBJECT_MOVE: + _local_9 = false; + this.setFurnitureAlphaMultiplier(roomObject, 0.5); + this.setSelectedRoomObjectData(roomId, roomObject.id, category, roomObject.getLocation(), roomObject.getDirection(), operation); + this._roomEngine._Str_16645(roomObject.id, category, true); + this._roomEngine._Str_7972(false); + break; + case RoomObjectOperationType.OBJECT_MOVE_TO: { + const selectedData = this.getSelectedRoomObjectData(roomId); + + this._Str_16022(roomId, selectedData.id, selectedData.category, selectedData.loc, selectedData.dir, RoomObjectOperationType.OBJECT_MOVE_TO, selectedData.typeId, selectedData._Str_4766, selectedData.stuffData, selectedData.state, selectedData._Str_15896, selectedData.posture); + this.setFurnitureAlphaMultiplier(roomObject, 1); + this._roomEngine._Str_17948(); + + if(this._roomEngine.connection) + { + if(category === RoomObjectCategory.FLOOR) + { + const angle = ((roomObject.getDirection().x) % 360); + const location = roomObject.getLocation(); + const direction = (angle / 45); + + this._roomEngine.connection.send(new FurnitureFloorUpdateComposer(objectId, location.x, location.y, direction)); + } + + else if(category === RoomObjectCategory.WALL) + { + const angle = ((roomObject.getDirection().x) % 360); + const wallGeometry = this._roomEngine.getLegacyWallGeometry(roomId); + + if(wallGeometry) + { + const location = wallGeometry._Str_21860(roomObject.getLocation(), angle); + + if(location) this._roomEngine.connection.send(new FurnitureWallUpdateComposer(objectId, location)); + } + } + + else if(category === RoomObjectCategory.UNIT) + { + const angle = ((roomObject.getDirection().x) % 360); + const location = roomObject.getLocation(); + const direction = (angle / 45); + const race = parseInt(roomObject.model.getValue(RoomObjectVariable.RACE)); + const roomSession = this._roomEngine.roomSessionManager.getSession(roomId); + + if(roomSession) + { + const userData = roomSession.userDataManager.getUserDataByIndex(objectId); + + if(userData) this._roomEngine.connection.send(new PetMoveComposer(userData.webID, location.x, location.y, direction)); + } + } + } + + break; + } + } + + if(_local_9) this._Str_13199(roomId); + + return true; + } + + public _Str_17555(k: IRoomObjectController, _arg_2: boolean): number + { + if(!k || !k.model) return 0; + + let _local_6 = 0; + let _local_7 = 0; + let allowedDirections: number[] = []; + + if(k.type === RoomObjectUserType.MONSTER_PLANT) + { + allowedDirections = k.model.getValue(RoomObjectVariable.PET_ALLOWED_DIRECTIONS); + } + else + { + allowedDirections = k.model.getValue(RoomObjectVariable.FURNITURE_ALLOWED_DIRECTIONS); + } + + let direction = k.getDirection().x; + + if(allowedDirections && allowedDirections.length) + { + _local_6 = allowedDirections.indexOf(direction); + + if(_local_6 < 0) + { + _local_6 = 0; + _local_7 = 0; + + while(_local_7 < allowedDirections.length) + { + if(direction <= allowedDirections[_local_7]) break; + + _local_6++; + _local_7++; + } + + _local_6 = (_local_6 % allowedDirections.length); + } + + if(_arg_2) _local_6 = ((_local_6 + 1) % allowedDirections.length); + else _local_6 = (((_local_6 - 1) + allowedDirections.length) % allowedDirections.length); + + direction = allowedDirections[_local_6]; + } + + return direction; + } + + private isValidLocation(object: IRoomObject, goalDirection: IVector3D, stackingHeightMap: FurnitureStackingHeightMap): boolean + { + if(!object || !object.model || !goalDirection) return false; + + const direction = object.getDirection(); + const location = object.getLocation(); + + if(!direction || !location) return false; + + if((direction.x % 180) === (goalDirection.x % 180)) return true; + + let sizeX = object.model.getValue(RoomObjectVariable.FURNITURE_SIZE_X); + let sizeY = object.model.getValue(RoomObjectVariable.FURNITURE_SIZE_Y); + + if(sizeX < 1) sizeX = 1; + + if(sizeY < 1) sizeY = 1; + + let _local_8 = sizeX; + let _local_9 = sizeY; + + let _local_11 = (Math.trunc((Math.trunc((goalDirection.x + 45)) % 360) / 90)); + + if((_local_11 === 1) || (_local_11 === 3)) [ sizeX, sizeY ] = [ sizeY, sizeX ]; + + _local_11 = (Math.trunc((Math.trunc((direction.x + 45)) % 360) / 90)); + + if(((_local_11 === 1) || (_local_11 === 3))) [ _local_8, _local_9 ] = [ _local_9, _local_8 ]; + + if(stackingHeightMap && location) + { + const alwaysStackable = (object.model.getValue(RoomObjectVariable.FURNITURE_ALWAYS_STACKABLE) === 1); + + if(stackingHeightMap.validateLocation(location.x, location.y, sizeX, sizeY, location.x, location.y, _local_8, _local_9, alwaysStackable, location.z)) return true; + } + + return false; + } + + private _Str_19253(roomId: number, objectId: number, category: number): void + { + const _local_4 = this.getSelectedRoomObjectData(roomId); + + if(!_local_4) return; + + const _local_5 = (this._roomEngine.getRoomObject(roomId, objectId, category) as IRoomObjectController); + + if(!_local_5) return; + + if(!this._roomEngine || !this._roomEngine.events) return; + + this._roomEngine.events.dispatchEvent(new RoomEngineObjectPlacedOnUserEvent(RoomEngineObjectEvent.PLACED_ON_USER, roomId, objectId, category, _local_4.id, _local_4.category)); + } + + public _Str_17481(roomId: number, objectId: number, category: number): void + { + if(!this._roomEngine) return; + + const eventDispatcher = this._roomEngine.events; + + if(!eventDispatcher) return; + + switch(category) + { + case RoomObjectCategory.UNIT: + case RoomObjectCategory.FLOOR: + case RoomObjectCategory.WALL: + if(category === RoomObjectCategory.UNIT) + { + this._Str_16209(roomId); + this._Str_12227(roomId, objectId, true); + } + else + { + this._Str_12227(roomId, 0, false); + + if(objectId !== this._selectedObjectId) + { + this._Str_16209(roomId); + + const _local_5 = this._roomEngine.getRoomObject(roomId, objectId, category); + + if(_local_5 && _local_5.logic) + { + _local_5.logic.processUpdateMessage(new ObjectSelectedMessage(true)); + + this._selectedObjectId = objectId; + this._selectedObjectCategory = category; + } + } + } + + eventDispatcher.dispatchEvent(new RoomEngineObjectEvent(RoomEngineObjectEvent.SELECTED, roomId, objectId, category)); + + return; + } + } + + private _Str_16209(k: number): void + { + if(this._selectedObjectId === -1) return; + + const object = this._roomEngine.getRoomObject(k, this._selectedObjectId, this._selectedObjectCategory); + + if(object && object.logic) + { + object.logic.processUpdateMessage(new ObjectSelectedMessage(false)); + + this._selectedObjectId = -1; + this._selectedObjectCategory = RoomObjectCategory.MINIMUM; + } + } + + public _Str_12227(k: number, _arg_2: number, _arg_3: boolean): void + { + if(!this._roomEngine) return; + + const _local_4 = RoomObjectCategory.UNIT; + const _local_5 = this._roomEngine.getRoomObject(k, this._selectedAvatarId, _local_4); + + if(_local_5 && _local_5.logic) + { + _local_5.logic.processUpdateMessage(new ObjectAvatarSelectedMessage(false)); + + this._selectedAvatarId = -1; + } + + let _local_6 = false; + + if(_arg_3) + { + const _local_5 = this._roomEngine.getRoomObject(k, _arg_2, _local_4); + + if(_local_5 && _local_5.logic) + { + _local_5.logic.processUpdateMessage(new ObjectAvatarSelectedMessage(true)); + + _local_6 = true; + + this._selectedAvatarId = _arg_2; + + const location = _local_5.getLocation(); + + if(location) this._roomEngine.connection.send(new RoomUnitLookComposer(~~(location.x), ~~(location.y))); + } + } + + const selectionArrow = this._roomEngine.getRoomObjectSelectionArrow(k); + + if(selectionArrow && selectionArrow.logic) + { + if(_local_6 && !this._roomEngine.isPlayingGame()) selectionArrow.logic.processUpdateMessage(new ObjectVisibilityUpdateMessage(ObjectVisibilityUpdateMessage.ENABLED)); + else selectionArrow.logic.processUpdateMessage(new ObjectVisibilityUpdateMessage(ObjectVisibilityUpdateMessage.DISABLED)); + } + } + + private _Str_13199(roomId: number): void + { + if(!this._roomEngine) return; + + this._roomEngine._Str_17948(); + + const selectedData = this.getSelectedRoomObjectData(roomId); + + if(selectedData) + { + if((selectedData.operation === RoomObjectOperationType.OBJECT_MOVE) || (selectedData.operation === RoomObjectOperationType.OBJECT_MOVE_TO)) + { + const roomObject = this._roomEngine.getRoomObject(roomId, selectedData.id, selectedData.category); + + if(roomObject && (selectedData.operation !== RoomObjectOperationType.OBJECT_MOVE_TO)) + { + roomObject.setLocation(selectedData.loc); + roomObject.setDirection(selectedData.dir); + } + + this.setFurnitureAlphaMultiplier(roomObject, 1); + + if(selectedData.category === RoomObjectCategory.WALL) + { + this._roomEngine.updateRoomObjectMask(roomId, selectedData.id, true); + } + + this._Str_16022(roomId, selectedData.id, selectedData.category, selectedData.loc, selectedData.dir, RoomObjectOperationType.OBJECT_MOVE, selectedData.typeId, selectedData._Str_4766, selectedData.stuffData, selectedData.state, selectedData._Str_15896, selectedData.posture); + } + + else if((selectedData.operation === RoomObjectOperationType.OBJECT_PLACE)) + { + const objectId = selectedData.id; + const category = selectedData.category; + + switch(category) + { + case RoomObjectCategory.FLOOR: + this._roomEngine.removeRoomObjectFloor(roomId, objectId); + break; + case RoomObjectCategory.WALL: + this._roomEngine.removeRoomObjectWall(roomId, objectId); + break; + case RoomObjectCategory.UNIT: + this._roomEngine.removeRoomObjectUser(roomId, objectId); + break; + } + } + + this._roomEngine.setSelectedRoomObjectData(roomId, null); + } + } + + private getSelectedRoomObjectData(roomId: number): SelectedRoomObjectData + { + if(!this._roomEngine) return null; + + return this._roomEngine.getSelectedRoomObjectData(roomId); + } + + private setFurnitureAlphaMultiplier(object: IRoomObjectController, multiplier: number): void + { + if(!object || !object.model) return; + + object.model.setValue(RoomObjectVariable.FURNITURE_ALPHA_MULTIPLIER, multiplier); + } + + private _Str_25211(event: RoomObjectMouseEvent): boolean + { + return (this._roomEngine.isDecorating) && (!(event.ctrlKey || event.shiftKey)); + } + + public cancelRoomObjectPlacement(roomId: number): boolean + { + this._Str_13199(roomId); + + return true; + } + + private setSelectedRoomObjectData(roomId: number, id: number, category: number, location: IVector3D, direction: IVector3D, operation: string, typeId: number = 0, instanceData: string = null, stuffData: IObjectData =null, state: number = -1, frameNumber: number = -1, posture: string = null): void + { + this._Str_13199(roomId); + + if(!this._roomEngine) return; + + const selectedData = new SelectedRoomObjectData(id, category, operation, location, direction, typeId, instanceData, stuffData, state, frameNumber, posture); + + this._roomEngine.setSelectedRoomObjectData(roomId, selectedData); + } + + private _Str_16022(roomId: number, id: number, category: number, location: IVector3D, direction: IVector3D, operation: string, typeId: number = 0, instanceData: string = null, stuffData: IObjectData = null, state: number = -1, frameNumber: number = -1, posture: string = null): void + { + if(!this._roomEngine) return null; + + const selectedData = new SelectedRoomObjectData(id, category, operation, location, direction, typeId, instanceData, stuffData, state, frameNumber, posture); + + this._roomEngine.setSelectedRoomObjectData(roomId, selectedData); + } + + private _Str_25586(roomObject: IRoomObjectController, x: number, y: number, wallGeometry: LegacyWallGeometry): boolean + { + if(!wallGeometry._Str_10375(x, y)) return false; + + roomObject.setLocation(new Vector3d(x, y, wallGeometry.getHeight(x, y))); + + return true; + } + + public modifyWallItemData(roomId: number, objectId: number, colorHex: string, text: string): boolean + { + if(!this._roomEngine || !this._roomEngine.connection) + { + return false; + } + + this._roomEngine.connection.send(new ModifyWallItemDataComposer(objectId, colorHex, text)); + + return true; + } + + public deleteWallItem(roomId: number, itemId: number): boolean + { + if(!this._roomEngine || !this._roomEngine.connection) + { + return false; + } + + this._roomEngine.connection.send(new RemoveWallItemComposer(itemId)); + + return true; + } + + public get engine(): IRoomEngineServices + { + return this._roomEngine; + } + + public get selectedAvatarId(): number + { + return this._selectedAvatarId; + } +} diff --git a/src/nitro/room/RoomObjectLogicFactory.ts b/src/nitro/room/RoomObjectLogicFactory.ts new file mode 100644 index 00000000..6d428e19 --- /dev/null +++ b/src/nitro/room/RoomObjectLogicFactory.ts @@ -0,0 +1,304 @@ +import { NitroLogger } from '../../core/common/logger/NitroLogger'; +import { EventDispatcher } from '../../core/events/EventDispatcher'; +import { IEventDispatcher } from '../../core/events/IEventDispatcher'; +import { IRoomObjectEventHandler } from '../../room/object/logic/IRoomObjectEventHandler'; +import { IRoomObjectLogicFactory } from '../../room/object/logic/IRoomObjectLogicFactory'; +import { RoomObjectLogicBase } from '../../room/object/logic/RoomObjectLogicBase'; +import { AvatarLogic } from './object/logic/avatar/AvatarLogic'; +import { FurnitureBadgeDisplayLogic } from './object/logic/furniture/FurnitureBadgeDisplayLogic'; +import { FurnitureChangeStateWhenStepOnLogic } from './object/logic/furniture/FurnitureChangeStateWhenStepOnLogic'; +import { FurnitureCounterClockLogic } from './object/logic/furniture/FurnitureCounterClockLogic'; +import { FurnitureCrackableLogic } from './object/logic/furniture/FurnitureCrackableLogic'; +import { FurnitureCreditLogic } from './object/logic/furniture/FurnitureCreditLogic'; +import { FurnitureCustomStackHeightLogic } from './object/logic/furniture/FurnitureCustomStackHeightLogic'; +import { FurnitureDiceLogic } from './object/logic/furniture/FurnitureDiceLogic'; +import { FurnitureEditableInternalLinkLogic } from './object/logic/furniture/FurnitureEditableInternalLinkLogic'; +import { FurnitureEditableRoomLinkLogic } from './object/logic/furniture/FurnitureEditableRoomLinkLogic'; +import { FurnitureExternalImageLogic } from './object/logic/furniture/FurnitureExternalImageLogic'; +import { FurnitureFireworksLogic } from './object/logic/furniture/FurnitureFireworksLogic'; +import { FurnitureFloorHoleLogic } from './object/logic/furniture/FurnitureFloorHoleLogic'; +import { FurnitureFriendLogic } from './object/logic/furniture/FurnitureFriendLogic'; +import { FurnitureGuildCustomizedLogic } from './object/logic/furniture/FurnitureGuildCustomizedLogic'; +import { FurnitureHighScoreLogic } from './object/logic/furniture/FurnitureHighScoreLogic'; +import { FurnitureHockeyScoreLogic } from './object/logic/furniture/FurnitureHockeyScoreLogic'; +import { FurnitureIceStormLogic } from './object/logic/furniture/FurnitureIceStormLogic'; +import { FurnitureLogic } from './object/logic/furniture/FurnitureLogic'; +import { FurnitureMannequinLogic } from './object/logic/furniture/FurnitureMannequinLogic'; +import { FurnitureMultiHeightLogic } from './object/logic/furniture/FurnitureMultiHeightLogic'; +import { FurnitureMultiStateLogic } from './object/logic/furniture/FurnitureMultiStateLogic'; +import { FurnitureOneWayDoorLogic } from './object/logic/furniture/FurnitureOneWayDoorLogic'; +import { FurniturePetCustomizationLogic } from './object/logic/furniture/FurniturePetCustomizationLogic'; +import { FurniturePresentLogic } from './object/logic/furniture/FurniturePresentLogic'; +import { FurniturePurchaseableClothingLogic } from './object/logic/furniture/FurniturePurchaseableClothingLogic'; +import { FurniturePushableLogic } from './object/logic/furniture/FurniturePushableLogic'; +import { FurnitureRoomBackgroundColorLogic } from './object/logic/furniture/FurnitureRoomBackgroundColorLogic'; +import { FurnitureRoomBackgroundLogic } from './object/logic/furniture/FurnitureRoomBackgroundLogic'; +import { FurnitureRoomBillboardLogic } from './object/logic/furniture/FurnitureRoomBillboardLogic'; +import { FurnitureRoomDimmerLogic } from './object/logic/furniture/FurnitureRoomDimmerLogic'; +import { FurnitureScoreLogic } from './object/logic/furniture/FurnitureScoreLogic'; +import { FurnitureSoundBlockLogic } from './object/logic/furniture/FurnitureSoundBlockLogic'; +import { FurnitureStickieLogic } from './object/logic/furniture/FurnitureStickieLogic'; +import { FurnitureTrophyLogic } from './object/logic/furniture/FurnitureTrophyLogic'; +import { FurnitureVoteCounterLogic } from './object/logic/furniture/FurnitureVoteCounterLogic'; +import { FurnitureVoteMajorityLogic } from './object/logic/furniture/FurnitureVoteMajorityLogic'; +import { FurnitureWindowLogic } from './object/logic/furniture/FurnitureWindowLogic'; +import { FurnitureYoutubeLogic } from './object/logic/furniture/FurnitureYoutubeLogic'; +import { PetLogic } from './object/logic/pet/PetLogic'; +import { RoomLogic } from './object/logic/room/RoomLogic'; +import { SelectionArrowLogic } from './object/logic/room/SelectionArrowLogic'; +import { TileCursorLogic } from './object/logic/room/TileCursorLogic'; +import { RoomObjectLogicType } from './object/RoomObjectLogicType'; + +export class RoomObjectLogicFactory implements IRoomObjectLogicFactory +{ + private _events: IEventDispatcher; + + private _cachedEvents: Map; + private _registeredEvents: Map; + private _functions: Function[]; + + constructor() + { + this._events = new EventDispatcher(); + + this._cachedEvents = new Map(); + this._registeredEvents = new Map(); + this._functions = []; + } + + public getLogic(type: string): IRoomObjectEventHandler + { + const logic = this.getLogicType(type); + + if(!logic) return null; + + const instance = (new logic() as IRoomObjectEventHandler); + + if(!instance) return null; + + instance.eventDispatcher = this._events; + + if(!this._cachedEvents.get(type)) + { + this._cachedEvents.set(type, true); + + const eventTypes = instance.getEventTypes(); + + for(const eventType of eventTypes) + { + if(!eventType) continue; + + this.registerEventType(eventType); + } + } + + return instance; + } + + private registerEventType(type: string): void + { + if(this._registeredEvents.get(type)) return; + + this._registeredEvents.set(type, true); + + for(const func of this._functions) + { + if(!func) continue; + + this._events.addEventListener(type, func); + } + } + + public registerEventFunction(func: Function): void + { + if(!func) return; + + if(this._functions.indexOf(func) >= 0) return; + + this._functions.push(func); + + for(const eventType of this._registeredEvents.keys()) + { + if(!eventType) continue; + + this._events.addEventListener(eventType, func); + } + } + + public removeEventFunction(func: Function): void + { + if(!func) return; + + const index = this._functions.indexOf(func); + + if(index === -1) return; + + this._functions.splice(index, 1); + + for(const event of this._registeredEvents.keys()) + { + if(!event) continue; + + this._events.removeEventListener(event, func); + } + } + + public getLogicType(type: string): typeof RoomObjectLogicBase + { + if(!type) return null; + + let logic: typeof RoomObjectLogicBase = null; + + switch(type) + { + case RoomObjectLogicType.ROOM: + logic = RoomLogic; + break; + case RoomObjectLogicType.TILE_CURSOR: + logic = TileCursorLogic; + break; + case RoomObjectLogicType.SELECTION_ARROW: + logic = SelectionArrowLogic; + break; + case RoomObjectLogicType.USER: + case RoomObjectLogicType.BOT: + case RoomObjectLogicType.RENTABLE_BOT: + logic = AvatarLogic; + break; + case RoomObjectLogicType.PET: + logic = PetLogic; + break; + case RoomObjectLogicType.FURNITURE_BASIC: + logic = FurnitureLogic; + break; + case RoomObjectLogicType.FURNITURE_BADGE_DISPLAY: + logic = FurnitureBadgeDisplayLogic; + break; + case RoomObjectLogicType.FURNITURE_CHANGE_STATE_WHEN_STEP_ON: + logic = FurnitureChangeStateWhenStepOnLogic; + break; + case RoomObjectLogicType.FURNITURE_COUNTER_CLOCK: + logic = FurnitureCounterClockLogic; + break; + case RoomObjectLogicType.FURNITURE_CRACKABLE: + logic = FurnitureCrackableLogic; + break; + case RoomObjectLogicType.FURNITURE_CREDIT: + logic = FurnitureCreditLogic; + break; + case RoomObjectLogicType.FURNITURE_CUSTOM_STACK_HEIGHT: + logic = FurnitureCustomStackHeightLogic; + break; + case RoomObjectLogicType.FURNITURE_DICE: + logic = FurnitureDiceLogic; + break; + case RoomObjectLogicType.FURNITURE_EDITABLE_INTERNAL_LINK: + logic = FurnitureEditableInternalLinkLogic; + break; + case RoomObjectLogicType.FURNITURE_EDITABLE_ROOM_LINK: + logic = FurnitureEditableRoomLinkLogic; + break; + case RoomObjectLogicType.FURNITURE_EXTERNAL_IMAGE_WALLITEM: + logic = FurnitureExternalImageLogic; + break; + case RoomObjectLogicType.FURNITURE_FIREWORKS: + logic = FurnitureFireworksLogic; + break; + case RoomObjectLogicType.FURNITURE_FLOOR_HOLE: + logic = FurnitureFloorHoleLogic; + break; + case RoomObjectLogicType.FURNITURE_GUILD_CUSTOMIZED: + logic = FurnitureGuildCustomizedLogic; + break; + case RoomObjectLogicType.FURNITURE_HIGH_SCORE: + logic = FurnitureHighScoreLogic; + break; + case RoomObjectLogicType.FURNITURE_HOCKEY_SCORE: + logic = FurnitureHockeyScoreLogic; + break; + case RoomObjectLogicType.FURNITURE_ES: + logic = FurnitureIceStormLogic; + break; + case RoomObjectLogicType.FURNITURE_MANNEQUIN: + logic = FurnitureMannequinLogic; + break; + case RoomObjectLogicType.FURNITURE_MULTIHEIGHT: + logic = FurnitureMultiHeightLogic; + break; + case RoomObjectLogicType.FURNITURE_MULTISTATE: + logic = FurnitureMultiStateLogic; + break; + case RoomObjectLogicType.FURNITURE_ONE_WAY_DOOR: + logic = FurnitureOneWayDoorLogic; + break; + case RoomObjectLogicType.FURNITURE_PET_CUSTOMIZATION: + logic = FurniturePetCustomizationLogic; + break; + case RoomObjectLogicType.FURNITURE_PRESENT: + logic = FurniturePresentLogic; + break; + case RoomObjectLogicType.FURNITURE_PURCHASABLE_CLOTHING: + logic = FurniturePurchaseableClothingLogic; + break; + case RoomObjectLogicType.FURNITURE_PUSHABLE: + logic = FurniturePushableLogic; + break; + case RoomObjectLogicType.FURNITURE_BACKGROUND_COLOR: + logic = FurnitureRoomBackgroundColorLogic; + break; + case RoomObjectLogicType.FURNITURE_BG: + logic = FurnitureRoomBackgroundLogic; + break; + case RoomObjectLogicType.FURNITURE_BB: + logic = FurnitureRoomBillboardLogic; + break; + case RoomObjectLogicType.FURNITURE_ROOMDIMMER: + logic = FurnitureRoomDimmerLogic; + break; + case RoomObjectLogicType.FURNITURE_SCORE: + logic = FurnitureScoreLogic; + break; + case RoomObjectLogicType.FURNITURE_SOUNDBLOCK: + logic = FurnitureSoundBlockLogic; + break; + case RoomObjectLogicType.FURNITURE_STICKIE: + logic = FurnitureStickieLogic; + break; + case RoomObjectLogicType.FURNITURE_TROPHY: + logic = FurnitureTrophyLogic; + break; + case RoomObjectLogicType.FURNITURE_VOTE_COUNTER: + logic = FurnitureVoteCounterLogic; + break; + case RoomObjectLogicType.FURNITURE_VOTE_MAJORITY: + logic = FurnitureVoteMajorityLogic; + break; + case RoomObjectLogicType.FURNITURE_WINDOW: + logic = FurnitureWindowLogic; + break; + case RoomObjectLogicType.FURNITURE_LOVELOCK: + logic = FurnitureFriendLogic; + break; + case RoomObjectLogicType.FURNITURE_YOUTUBE: + logic = FurnitureYoutubeLogic; + break; + default: + logic = FurnitureLogic; + break; + } + + if(!logic) + { + NitroLogger.log(`Unknown Logic: ${ type }`); + + return null; + } + + return logic; + } + + public get events(): IEventDispatcher + { + return this._events; + } +} diff --git a/src/nitro/room/RoomVariableEnum.ts b/src/nitro/room/RoomVariableEnum.ts new file mode 100644 index 00000000..288efb2f --- /dev/null +++ b/src/nitro/room/RoomVariableEnum.ts @@ -0,0 +1,14 @@ +export class RoomVariableEnum +{ + public static ROOM_MIN_X: string = 'room_min_x'; + public static ROOM_MAX_X: string = 'room_max_x'; + public static ROOM_MIN_Y: string = 'room_min_y'; + public static ROOM_MAX_Y: string = 'room_max_y'; + public static ROOM_IS_PUBLIC: string = 'room_is_public'; + public static ROOM_Z_SCALE: string = 'room_z_scale'; + public static AD_DISPLAY_DELAY: string = 'ad_display_delay'; + public static IS_PLAYING_GAME: string = 'is_playing_game'; + public static RESTRICTS_DRAGGING: string = 'restricts_dragging'; + public static RESTRICTS_SCALING: string = 'restricts_scaling'; + public static RESTRICTED_SCALE: string = 'room_scale'; +} \ No newline at end of file diff --git a/src/nitro/room/enums/FriendFurniEngravingWidgetType.ts b/src/nitro/room/enums/FriendFurniEngravingWidgetType.ts new file mode 100644 index 00000000..3cd762d8 --- /dev/null +++ b/src/nitro/room/enums/FriendFurniEngravingWidgetType.ts @@ -0,0 +1,8 @@ +export class FriendFurniEngravingWidgetType +{ + public static readonly _Str_13451:number = 0; + public static readonly _Str_17498:number = 1; + public static readonly _Str_18746:number = 2; + public static readonly _Str_15230:number = 3; + public static readonly _Str_15778:number = 4; +} diff --git a/src/nitro/room/enums/RoomObjectPlacementSource.ts b/src/nitro/room/enums/RoomObjectPlacementSource.ts new file mode 100644 index 00000000..218a07ca --- /dev/null +++ b/src/nitro/room/enums/RoomObjectPlacementSource.ts @@ -0,0 +1,5 @@ +export class RoomObjectPlacementSource +{ + public static CATALOG: string = 'catalog'; + public static INVENTORY: string = 'inventory'; +} diff --git a/src/nitro/room/events/RoomBackgroundColorEvent.ts b/src/nitro/room/events/RoomBackgroundColorEvent.ts new file mode 100644 index 00000000..0b814630 --- /dev/null +++ b/src/nitro/room/events/RoomBackgroundColorEvent.ts @@ -0,0 +1,34 @@ +import { RoomEngineEvent } from './RoomEngineEvent'; + +export class RoomBackgroundColorEvent extends RoomEngineEvent +{ + public static ROOM_COLOR: string = 'REE_ROOM_COLOR'; + + private _color: number; + private _Str_21672: number; + private _Str_6930: boolean; + + constructor(roomId: number, color: number, _arg_3: number, _arg_4: boolean) + { + super(RoomBackgroundColorEvent.ROOM_COLOR, roomId); + + this._color = color; + this._Str_21672 = _arg_3; + this._Str_6930 = _arg_4; + } + + public get color(): number + { + return this._color; + } + + public get _Str_5123(): number + { + return this._Str_21672; + } + + public get _Str_11464(): boolean + { + return this._Str_6930; + } +} \ No newline at end of file diff --git a/src/nitro/room/events/RoomEngineDimmerStateEvent.ts b/src/nitro/room/events/RoomEngineDimmerStateEvent.ts new file mode 100644 index 00000000..754072a1 --- /dev/null +++ b/src/nitro/room/events/RoomEngineDimmerStateEvent.ts @@ -0,0 +1,48 @@ +import { RoomEngineEvent } from './RoomEngineEvent'; + +export class RoomEngineDimmerStateEvent extends RoomEngineEvent +{ + public static ROOM_COLOR: string = 'REDSE_ROOM_COLOR'; + + private _state: number; + private _presetId: number; + private _effectId: number; + private _color: number; + private _brightness: number; + + constructor(k: number, state: number, presetId: number, effectId: number, color: number, brightness: number) + { + super(RoomEngineDimmerStateEvent.ROOM_COLOR, k); + + this._state = state; + this._presetId = presetId; + this._effectId = effectId; + this._color = color; + this._brightness = brightness; + } + + public get state(): number + { + return this._state; + } + + public get _Str_14686(): number + { + return this._presetId; + } + + public get _Str_6815(): number + { + return this._effectId; + } + + public get color(): number + { + return this._color; + } + + public get _Str_5123(): number + { + return this._brightness; + } +} \ No newline at end of file diff --git a/src/nitro/room/events/RoomEngineEvent.ts b/src/nitro/room/events/RoomEngineEvent.ts new file mode 100644 index 00000000..067ed9fd --- /dev/null +++ b/src/nitro/room/events/RoomEngineEvent.ts @@ -0,0 +1,26 @@ +import { NitroEvent } from '../../../core/events/NitroEvent'; + +export class RoomEngineEvent extends NitroEvent +{ + public static INITIALIZED: string = 'REE_INITIALIZED'; + public static ENGINE_INITIALIZED: string = 'REE_ENGINE_INITIALIZED'; + public static OBJECTS_INITIALIZED: string = 'REE_OBJECTS_INITIALIZED'; + public static NORMAL_MODE: string = 'REE_NORMAL_MODE'; + public static GAME_MODE: string = 'REE_GAME_MODE'; + public static ROOM_ZOOMED: string = 'REE_ROOM_ZOOMED'; + public static DISPOSED: string = 'REE_DISPOSED'; + + private _roomId: number; + + constructor(type: string, roomId: number) + { + super(type); + + this._roomId = roomId; + } + + public get roomId(): number + { + return this._roomId; + } +} \ No newline at end of file diff --git a/src/nitro/room/events/RoomEngineObjectEvent.ts b/src/nitro/room/events/RoomEngineObjectEvent.ts new file mode 100644 index 00000000..04f78656 --- /dev/null +++ b/src/nitro/room/events/RoomEngineObjectEvent.ts @@ -0,0 +1,37 @@ +import { RoomEngineEvent } from './RoomEngineEvent'; + +export class RoomEngineObjectEvent extends RoomEngineEvent +{ + public static SELECTED: string = 'REOE_SELECTED'; + public static DESELECTED: string = 'REOE_DESELECTED'; + public static ADDED: string = 'REOE_ADDED'; + public static REMOVED: string = 'REOE_REMOVED'; + public static PLACED: string = 'REOE_PLACED'; + public static PLACED_ON_USER: string = 'REOE_PLACED_ON_USER'; + public static CONTENT_UPDATED: string = 'REOE_CONTENT_UPDATED'; + public static REQUEST_MOVE: string = 'REOE_REQUEST_MOVE'; + public static REQUEST_ROTATE: string = 'REOE_REQUEST_ROTATE'; + public static MOUSE_ENTER: string = 'REOE_MOUSE_ENTER'; + public static MOUSE_LEAVE: string = 'REOE_MOUSE_LEAVE'; + + private _objectId: number; + private _category: number; + + constructor(type: string, roomId: number, objectId: number, category: number) + { + super(type, roomId); + + this._objectId = objectId; + this._category = category; + } + + public get objectId(): number + { + return this._objectId; + } + + public get category(): number + { + return this._category; + } +} \ No newline at end of file diff --git a/src/nitro/room/events/RoomEngineObjectPlacedEvent.ts b/src/nitro/room/events/RoomEngineObjectPlacedEvent.ts new file mode 100644 index 00000000..b9667a21 --- /dev/null +++ b/src/nitro/room/events/RoomEngineObjectPlacedEvent.ts @@ -0,0 +1,74 @@ +import { RoomEngineObjectEvent } from './RoomEngineObjectEvent'; + +export class RoomEngineObjectPlacedEvent extends RoomEngineObjectEvent +{ + private _wallLocation: string = ''; + private _x: number = 0; + private _y: number = 0; + private _z: number = 0; + private _direction: number = 0; + private _placedInRoom: boolean = false; + private _placedOnFloor: boolean = false; + private _placedOnWall: boolean = false; + private _instanceData: string = null; + + constructor(type: string, roomId: number, objectId: number, category: number, wallLocation: string, x: number, y: number, z: number, direction: number, placedInRoom: boolean, placedOnFloor: boolean, placedOnWall: boolean, instanceData: string) + { + super(type, roomId, objectId, category); + + this._wallLocation = wallLocation; + this._x = x; + this._y = y; + this._z = z; + this._direction = direction; + this._placedInRoom = placedInRoom; + this._placedOnFloor = placedOnFloor; + this._placedOnWall = placedOnWall; + this._instanceData = instanceData; + } + + public get _Str_7031(): string + { + return this._wallLocation; + } + + public get x(): number + { + return this._x; + } + + public get y(): number + { + return this._y; + } + + public get z(): number + { + return this._z; + } + + public get direction(): number + { + return this._direction; + } + + public get _Str_4057(): boolean + { + return this._placedInRoom; + } + + public get _Str_23888(): boolean + { + return this._placedOnFloor; + } + + public get _Str_23432(): boolean + { + return this._placedOnWall; + } + + public get _Str_4766(): string + { + return this._instanceData; + } +} \ No newline at end of file diff --git a/src/nitro/room/events/RoomEngineObjectPlacedOnUserEvent.ts b/src/nitro/room/events/RoomEngineObjectPlacedOnUserEvent.ts new file mode 100644 index 00000000..21f1e18e --- /dev/null +++ b/src/nitro/room/events/RoomEngineObjectPlacedOnUserEvent.ts @@ -0,0 +1,25 @@ +import { RoomEngineObjectEvent } from './RoomEngineObjectEvent'; + +export class RoomEngineObjectPlacedOnUserEvent extends RoomEngineObjectEvent +{ + private _droppedObjectId: number; + private _droppedObjectCategory: number; + + constructor(k: string, roomId: number, objectId: number, category: number, droppedObjectId: number, droppedObjectCategory: number) + { + super(k, roomId, objectId, category); + + this._droppedObjectId = droppedObjectId; + this._droppedObjectCategory = droppedObjectCategory; + } + + public get droppedObjectId(): number + { + return this._droppedObjectId; + } + + public get droppedObjectCategory(): number + { + return this._droppedObjectCategory; + } +} \ No newline at end of file diff --git a/src/nitro/room/events/RoomEngineSamplePlaybackEvent.ts b/src/nitro/room/events/RoomEngineSamplePlaybackEvent.ts new file mode 100644 index 00000000..5c017f51 --- /dev/null +++ b/src/nitro/room/events/RoomEngineSamplePlaybackEvent.ts @@ -0,0 +1,30 @@ +import { RoomEngineObjectEvent } from './RoomEngineObjectEvent'; + +export class RoomEngineSamplePlaybackEvent extends RoomEngineObjectEvent +{ + public static ROOM_OBJECT_INITIALIZED: string = 'ROPSPE_ROOM_OBJECT_INITIALIZED'; + public static ROOM_OBJECT_DISPOSED: string = 'ROPSPE_ROOM_OBJECT_DISPOSED'; + public static PLAY_SAMPLE: string = 'ROPSPE_PLAY_SAMPLE'; + public static CHANGE_PITCH: string = 'ROPSPE_CHANGE_PITCH'; + + private _sampleId: number; + private _pitch: number; + + constructor(k: string, roomId: number, objectId: number, objectCategory: number, sampleId: number, pitch: number = 1) + { + super(k, roomId, objectId, objectCategory); + + this._sampleId = sampleId; + this._pitch = pitch; + } + + public get sampleId(): number + { + return this._sampleId; + } + + public get pitch(): number + { + return this._pitch; + } +} diff --git a/src/nitro/room/events/RoomEngineTriggerWidgetEvent.ts b/src/nitro/room/events/RoomEngineTriggerWidgetEvent.ts new file mode 100644 index 00000000..3c84908d --- /dev/null +++ b/src/nitro/room/events/RoomEngineTriggerWidgetEvent.ts @@ -0,0 +1,50 @@ +import { RoomEngineObjectEvent } from './RoomEngineObjectEvent'; + +export class RoomEngineTriggerWidgetEvent extends RoomEngineObjectEvent +{ + public static OPEN_WIDGET: string = 'RETWE_OPEN_WIDGET'; + public static CLOSE_WIDGET: string = 'RETWE_CLOSE_WIDGET'; + public static OPEN_FURNI_CONTEXT_MENU: string = 'RETWE_OPEN_FURNI_CONTEXT_MENU'; + public static CLOSE_FURNI_CONTEXT_MENU: string = 'RETWE_CLOSE_FURNI_CONTEXT_MENU'; + public static REQUEST_PLACEHOLDER: string = 'RETWE_REQUEST_PLACEHOLDER'; + public static REQUEST_CREDITFURNI: string = 'RETWE_REQUEST_CREDITFURNI'; + public static REQUEST_STICKIE: string = 'RETWE_REQUEST_STICKIE'; + public static REQUEST_PRESENT: string = 'RETWE_REQUEST_PRESENT'; + public static REQUEST_TROPHY: string = 'RETWE_REQUEST_TROPHY'; + public static REQUEST_TEASER: string = 'RETWE_REQUEST_TEASER'; + public static REQUEST_ECOTRONBOX: string = 'RETWE_REQUEST_ECOTRONBOX'; + public static REQUEST_DIMMER: string = 'RETWE_REQUEST_DIMMER'; + public static REMOVE_DIMMER: string = 'RETWE_REMOVE_DIMMER'; + public static REQUEST_CLOTHING_CHANGE: string = 'RETWE_REQUEST_CLOTHING_CHANGE'; + public static REQUEST_PLAYLIST_EDITOR: string = 'RETWE_REQUEST_PLAYLIST_EDITOR'; + public static REQUEST_MANNEQUIN: string = 'RETWE_REQUEST_MANNEQUIN'; + public static REQUEST_MONSTERPLANT_SEED_PLANT_CONFIRMATION_DIALOG: string = 'ROWRE_REQUEST_MONSTERPLANT_SEED_PLANT_CONFIRMATION_DIALOG'; + public static REQUEST_PURCHASABLE_CLOTHING_CONFIRMATION_DIALOG: string = 'ROWRE_REQUEST_PURCHASABLE_CLOTHING_CONFIRMATION_DIALOG'; + public static REQUEST_BACKGROUND_COLOR: string = 'RETWE_REQUEST_BACKGROUND_COLOR'; + public static REQUEST_MYSTERYBOX_OPEN_DIALOG: string = 'RETWE_REQUEST_MYSTERYBOX_OPEN_DIALOG'; + public static REQUEST_EFFECTBOX_OPEN_DIALOG: string = 'RETWE_REQUEST_EFFECTBOX_OPEN_DIALOG'; + public static REQUEST_MYSTERYTROPHY_OPEN_DIALOG: string = 'RETWE_REQUEST_MYSTERYTROPHY_OPEN_DIALOG'; + public static REQUEST_ACHIEVEMENT_RESOLUTION_ENGRAVING: string = 'RETWE_REQUEST_ACHIEVEMENT_RESOLUTION_ENGRAVING'; + public static REQUEST_ACHIEVEMENT_RESOLUTION_FAILED: string = 'RETWE_REQUEST_ACHIEVEMENT_RESOLUTION_FAILED'; + public static REQUEST_FRIEND_FURNITURE_CONFIRM: string = 'RETWE_REQUEST_FRIEND_FURNITURE_CONFIRM'; + public static REQUEST_FRIEND_FURNITURE_ENGRAVING: string = 'RETWE_REQUEST_FRIEND_FURNITURE_ENGRAVING'; + public static REQUEST_BADGE_DISPLAY_ENGRAVING: string = 'RETWE_REQUEST_BADGE_DISPLAY_ENGRAVING'; + public static REQUEST_HIGH_SCORE_DISPLAY: string = 'RETWE_REQUEST_HIGH_SCORE_DISPLAY'; + public static REQUEST_HIDE_HIGH_SCORE_DISPLAY: string = 'RETWE_REQUEST_HIDE_HIGH_SCORE_DISPLAY'; + public static REQUEST_INTERNAL_LINK: string = 'RETWE_REQUEST_INTERNAL_LINK'; + public static REQUEST_ROOM_LINK: string = 'RETWE_REQUEST_ROOM_LINK'; + + private _widget: string + + constructor(type: string, roomId: number, objectId: number, category: number, widget: string = null) + { + super(type, roomId, objectId, category); + + this._widget = widget; + } + + public get widget(): string + { + return this._widget; + } +} \ No newline at end of file diff --git a/src/nitro/room/events/RoomObjectBadgeAssetEvent.ts b/src/nitro/room/events/RoomObjectBadgeAssetEvent.ts new file mode 100644 index 00000000..7708c997 --- /dev/null +++ b/src/nitro/room/events/RoomObjectBadgeAssetEvent.ts @@ -0,0 +1,28 @@ +import { RoomObjectEvent } from '../../../room/events/RoomObjectEvent'; +import { IRoomObject } from '../../../room/object/IRoomObject'; + +export class RoomObjectBadgeAssetEvent extends RoomObjectEvent +{ + public static LOAD_BADGE: string = 'ROBAE_LOAD_BADGE'; + + private _badgeId: string; + private _groupBadge: boolean; + + constructor(k: string, _arg_2: IRoomObject, badgeId: string, groupBadge: boolean = true) + { + super(k, _arg_2); + + this._badgeId = badgeId; + this._groupBadge = groupBadge; + } + + public get badgeId(): string + { + return this._badgeId; + } + + public get groupBadge(): boolean + { + return this._groupBadge; + } +} \ No newline at end of file diff --git a/src/nitro/room/events/RoomObjectDataRequestEvent.ts b/src/nitro/room/events/RoomObjectDataRequestEvent.ts new file mode 100644 index 00000000..382bae57 --- /dev/null +++ b/src/nitro/room/events/RoomObjectDataRequestEvent.ts @@ -0,0 +1,13 @@ +import { RoomObjectEvent } from '../../../room/events/RoomObjectEvent'; +import { IRoomObject } from '../../../room/object/IRoomObject'; + +export class RoomObjectDataRequestEvent extends RoomObjectEvent +{ + public static RODRE_CURRENT_USER_ID: string = 'RODRE_CURRENT_USER_ID'; + public static RODRE_URL_PREFIX: string = 'RODRE_URL_PREFIX'; + + constructor(type: string, object: IRoomObject) + { + super(type, object); + } +} diff --git a/src/nitro/room/events/RoomObjectDimmerStateUpdateEvent.ts b/src/nitro/room/events/RoomObjectDimmerStateUpdateEvent.ts new file mode 100644 index 00000000..572e3691 --- /dev/null +++ b/src/nitro/room/events/RoomObjectDimmerStateUpdateEvent.ts @@ -0,0 +1,49 @@ +import { RoomObjectEvent } from '../../../room/events/RoomObjectEvent'; +import { IRoomObject } from '../../../room/object/IRoomObject'; + +export class RoomObjectDimmerStateUpdateEvent extends RoomObjectEvent +{ + public static DIMMER_STATE: string = 'RODSUE_DIMMER_STATE'; + + private _state: number; + private _presetId: number; + private _effectId: number; + private _color: number; + private _brightness: number; + + constructor(object: IRoomObject, state: number, presetId: number, effectId: number, color: number, brightness: number) + { + super(RoomObjectDimmerStateUpdateEvent.DIMMER_STATE, object); + + this._state = state; + this._presetId = presetId; + this._effectId = effectId; + this._color = color; + this._brightness = brightness; + } + + public get state(): number + { + return this._state; + } + + public get _Str_14686(): number + { + return this._presetId; + } + + public get _Str_6815(): number + { + return this._effectId; + } + + public get color(): number + { + return this._color; + } + + public get _Str_5123(): number + { + return this._brightness; + } +} \ No newline at end of file diff --git a/src/nitro/room/events/RoomObjectFloorHoleEvent.ts b/src/nitro/room/events/RoomObjectFloorHoleEvent.ts new file mode 100644 index 00000000..610884cc --- /dev/null +++ b/src/nitro/room/events/RoomObjectFloorHoleEvent.ts @@ -0,0 +1,13 @@ +import { RoomObjectEvent } from '../../../room/events/RoomObjectEvent'; +import { IRoomObject } from '../../../room/object/IRoomObject'; + +export class RoomObjectFloorHoleEvent extends RoomObjectEvent +{ + public static ADD_HOLE: string = 'ROFHO_ADD_HOLE'; + public static REMOVE_HOLE: string = 'ROFHO_REMOVE_HOLE'; + + constructor(k: string, _arg_2: IRoomObject) + { + super(k, _arg_2); + } +} \ No newline at end of file diff --git a/src/nitro/room/events/RoomObjectFurnitureActionEvent.ts b/src/nitro/room/events/RoomObjectFurnitureActionEvent.ts new file mode 100644 index 00000000..2845ad61 --- /dev/null +++ b/src/nitro/room/events/RoomObjectFurnitureActionEvent.ts @@ -0,0 +1,20 @@ +import { RoomObjectEvent } from '../../../room/events/RoomObjectEvent'; + +export class RoomObjectFurnitureActionEvent extends RoomObjectEvent +{ + public static DICE_OFF: string = 'ROFCAE_DICE_OFF'; + public static DICE_ACTIVATE: string = 'ROFCAE_DICE_ACTIVATE'; + public static USE_HABBOWHEEL: string = 'ROFCAE_USE_HABBOWHEEL'; + public static STICKIE: string = 'ROFCAE_STICKIE'; + public static ENTER_ONEWAYDOOR: string = 'ROFCAE_ENTER_ONEWAYDOOR'; + public static SOUND_MACHINE_INIT: string = 'ROFCAE_SOUND_MACHINE_INIT'; + public static SOUND_MACHINE_START: string = 'ROFCAE_SOUND_MACHINE_START'; + public static SOUND_MACHINE_STOP: string = 'ROFCAE_SOUND_MACHINE_STOP'; + public static SOUND_MACHINE_DISPOSE: string = 'ROFCAE_SOUND_MACHINE_DISPOSE'; + public static JUKEBOX_INIT: string = 'ROFCAE_JUKEBOX_INIT'; + public static JUKEBOX_START: string = 'ROFCAE_JUKEBOX_START'; + public static JUKEBOX_MACHINE_STOP: string = 'ROFCAE_JUKEBOX_MACHINE_STOP'; + public static JUKEBOX_DISPOSE: string = 'ROFCAE_JUKEBOX_DISPOSE'; + public static MOUSE_BUTTON: string = 'ROFCAE_MOUSE_BUTTON'; + public static MOUSE_ARROW: string = 'ROFCAE_MOUSE_ARROW'; +} \ No newline at end of file diff --git a/src/nitro/room/events/RoomObjectHSLColorEnableEvent.ts b/src/nitro/room/events/RoomObjectHSLColorEnableEvent.ts new file mode 100644 index 00000000..cfa0e7a4 --- /dev/null +++ b/src/nitro/room/events/RoomObjectHSLColorEnableEvent.ts @@ -0,0 +1,42 @@ +import { RoomObjectEvent } from '../../../room/events/RoomObjectEvent'; +import { IRoomObject } from '../../../room/object/IRoomObject'; + +export class RoomObjectHSLColorEnableEvent extends RoomObjectEvent +{ + public static ROOM_BACKGROUND_COLOR: string = 'ROHSLCEE_ROOM_BACKGROUND_COLOR'; + + private _enable: boolean; + private _hue: number; + private _saturation: number; + private _lightness: number; + + constructor(k: string, _arg_2: IRoomObject, _arg_3: boolean, _arg_4: number, _arg_5: number, _arg_6: number) + { + super(k, _arg_2); + + this._enable = _arg_3; + this._hue = _arg_4; + this._saturation = _arg_5; + this._lightness = _arg_6; + } + + public get enable(): boolean + { + return this._enable; + } + + public get hue(): number + { + return this._hue; + } + + public get saturation(): number + { + return this._saturation; + } + + public get lightness(): number + { + return this._lightness; + } +} \ No newline at end of file diff --git a/src/nitro/room/events/RoomObjectHSLColorEnabledEvent.ts b/src/nitro/room/events/RoomObjectHSLColorEnabledEvent.ts new file mode 100644 index 00000000..9908e841 --- /dev/null +++ b/src/nitro/room/events/RoomObjectHSLColorEnabledEvent.ts @@ -0,0 +1,41 @@ +import { RoomEngineEvent } from './RoomEngineEvent'; + +export class RoomObjectHSLColorEnabledEvent extends RoomEngineEvent +{ + public static ROOM_BACKGROUND_COLOR: string = 'ROHSLCEE_ROOM_BACKGROUND_COLOR'; + + private _enable: boolean; + private _hue: number; + private _saturation: number; + private _lightness: number; + + constructor(k: string, _arg_2: number, _arg_3: boolean, _arg_4: number, _arg_5: number, _arg_6: number) + { + super(k, _arg_2); + + this._enable = _arg_3; + this._hue = _arg_4; + this._saturation = _arg_5; + this._lightness = _arg_6; + } + + public get enable(): boolean + { + return this._enable; + } + + public get hue(): number + { + return this._hue; + } + + public get saturation(): number + { + return this._saturation; + } + + public get lightness(): number + { + return this._lightness; + } +} \ No newline at end of file diff --git a/src/nitro/room/events/RoomObjectMoveEvent.ts b/src/nitro/room/events/RoomObjectMoveEvent.ts new file mode 100644 index 00000000..513870f3 --- /dev/null +++ b/src/nitro/room/events/RoomObjectMoveEvent.ts @@ -0,0 +1,13 @@ +import { RoomObjectEvent } from '../../../room/events/RoomObjectEvent'; +import { IRoomObject } from '../../../room/object/IRoomObject'; + +export class RoomObjectMoveEvent extends RoomObjectEvent +{ + public static POSITION_CHANGED: string = 'ROME_POSITION_CHANGED'; + public static OBJECT_REMOVED: string = 'ROME_OBJECT_REMOVED'; + + constructor(k: string, _arg_2: IRoomObject) + { + super(k, _arg_2); + } +} \ No newline at end of file diff --git a/src/nitro/room/events/RoomObjectSamplePlaybackEvent.ts b/src/nitro/room/events/RoomObjectSamplePlaybackEvent.ts new file mode 100644 index 00000000..712e4d39 --- /dev/null +++ b/src/nitro/room/events/RoomObjectSamplePlaybackEvent.ts @@ -0,0 +1,31 @@ +import { RoomObjectEvent } from '../../../room/events/RoomObjectEvent'; +import { IRoomObject } from '../../../room/object/IRoomObject'; + +export class RoomObjectSamplePlaybackEvent extends RoomObjectEvent +{ + public static ROOM_OBJECT_INITIALIZED: string = 'ROPSPE_ROOM_OBJECT_INITIALIZED'; + public static ROOM_OBJECT_DISPOSED: string = 'ROPSPE_ROOM_OBJECT_DISPOSED'; + public static PLAY_SAMPLE: string = 'ROPSPE_PLAY_SAMPLE'; + public static CHANGE_PITCH: string = 'ROPSPE_CHANGE_PITCH'; + + private _sampleId: number; + private _pitch: number; + + constructor(k: string, object: IRoomObject, sampleId: number, pitch: number = 1) + { + super(k, object); + + this._sampleId = sampleId; + this._pitch = pitch; + } + + public get sampleId(): number + { + return this._sampleId; + } + + public get pitch(): number + { + return this._pitch; + } +} diff --git a/src/nitro/room/events/RoomObjectStateChangedEvent.ts b/src/nitro/room/events/RoomObjectStateChangedEvent.ts new file mode 100644 index 00000000..252adb88 --- /dev/null +++ b/src/nitro/room/events/RoomObjectStateChangedEvent.ts @@ -0,0 +1,22 @@ +import { RoomObjectEvent } from '../../../room/events/RoomObjectEvent'; +import { IRoomObject } from '../../../room/object/IRoomObject'; + +export class RoomObjectStateChangedEvent extends RoomObjectEvent +{ + public static STATE_CHANGE: string = 'ROSCE_STATE_CHANGE'; + public static STATE_RANDOM: string = 'ROSCE_STATE_RANDOM'; + + private _state: number; + + constructor(type: string, object: IRoomObject, state: number = 0) + { + super(type, object); + + this._state = state; + } + + public get state(): number + { + return this._state; + } +} \ No newline at end of file diff --git a/src/nitro/room/events/RoomObjectTileMouseEvent.ts b/src/nitro/room/events/RoomObjectTileMouseEvent.ts new file mode 100644 index 00000000..f9ca55d9 --- /dev/null +++ b/src/nitro/room/events/RoomObjectTileMouseEvent.ts @@ -0,0 +1,48 @@ +import { RoomObjectMouseEvent } from '../../../room/events/RoomObjectMouseEvent'; +import { IRoomObject } from '../../../room/object/IRoomObject'; + +export class RoomObjectTileMouseEvent extends RoomObjectMouseEvent +{ + private _tileX: number; + private _tileY: number; + private _tileZ: number; + + constructor(type: string, object: IRoomObject, eventId: string, tileX: number, tileY: number, tileZ: number, altKey: boolean = false, ctrlKey: boolean = false, shiftKey: boolean = false, buttonDown: boolean = false) + { + super(type, object, eventId, altKey, ctrlKey, shiftKey, buttonDown); + + this._tileX = tileX; + this._tileY = tileY; + this._tileZ = tileZ; + } + + public get tileX(): number + { + return this._tileX; + } + + public get tileY(): number + { + return this._tileY; + } + + public get tileZ(): number + { + return this._tileZ; + } + + public get _Str_16836(): number + { + return Math.trunc(this._tileX + 0.499); + } + + public get _Str_17676(): number + { + return Math.trunc(this._tileY + 0.499); + } + + public get _Str_21459(): number + { + return Math.trunc(this._tileZ + 0.499); + } +} \ No newline at end of file diff --git a/src/nitro/room/events/RoomObjectWallMouseEvent.ts b/src/nitro/room/events/RoomObjectWallMouseEvent.ts new file mode 100644 index 00000000..1b8a1820 --- /dev/null +++ b/src/nitro/room/events/RoomObjectWallMouseEvent.ts @@ -0,0 +1,61 @@ +import { RoomObjectMouseEvent } from '../../../room/events/RoomObjectMouseEvent'; +import { IRoomObject } from '../../../room/object/IRoomObject'; +import { IVector3D } from '../../../room/utils/IVector3D'; +import { Vector3d } from '../../../room/utils/Vector3d'; + +export class RoomObjectWallMouseEvent extends RoomObjectMouseEvent +{ + private _wallLocation: Vector3d; + private _wallWd: Vector3d; + private _wallHt: Vector3d; + private _x: number; + private _y: number; + private _direction: number; + + constructor(type: string, object: IRoomObject, eventId: string, wallLocation: IVector3D, wallWidth: IVector3D, wallHeight: IVector3D, x: number, y: number, direction: number, altKey: boolean = false, ctrlKey: boolean = false, shiftKey: boolean = false, buttonDown: boolean = false) + { + super(type, object, eventId, altKey, ctrlKey, shiftKey, buttonDown); + + this._wallLocation = new Vector3d(); + this._wallWd = new Vector3d(); + this._wallHt = new Vector3d(); + + this._wallLocation.assign(wallLocation); + this._wallWd.assign(wallWidth); + this._wallHt.assign(wallHeight); + + this._x = x; + this._y = y; + this._direction = direction; + } + + public get wallLocation(): IVector3D + { + return this._wallLocation; + } + + public get wallWidth(): IVector3D + { + return this._wallWd; + } + + public get wallHeight(): IVector3D + { + return this._wallHt; + } + + public get x(): number + { + return this._x; + } + + public get y(): number + { + return this._y; + } + + public get direction(): number + { + return this._direction; + } +} \ No newline at end of file diff --git a/src/nitro/room/events/RoomObjectWidgetRequestEvent.ts b/src/nitro/room/events/RoomObjectWidgetRequestEvent.ts new file mode 100644 index 00000000..3b77259f --- /dev/null +++ b/src/nitro/room/events/RoomObjectWidgetRequestEvent.ts @@ -0,0 +1,45 @@ +import { RoomObjectEvent } from '../../../room/events/RoomObjectEvent'; +import { IRoomObject } from '../../../room/object/IRoomObject'; + +export class RoomObjectWidgetRequestEvent extends RoomObjectEvent +{ + public static OPEN_WIDGET: string = 'ROWRE_OPEN_WIDGET'; + public static CLOSE_WIDGET: string = 'ROWRE_CLOSE_WIDGET'; + public static OPEN_FURNI_CONTEXT_MENU: string = 'ROWRE_OPEN_FURNI_CONTEXT_MENU'; + public static CLOSE_FURNI_CONTEXT_MENU: string = 'ROWRE_CLOSE_FURNI_CONTEXT_MENU'; + public static PLACEHOLDER: string = 'ROWRE_PLACEHOLDER'; + public static CREDITFURNI: string = 'ROWRE__CREDITFURNI'; + public static STICKIE: string = 'ROWRE__STICKIE'; + public static PRESENT: string = 'ROWRE_PRESENT'; + public static TROPHY: string = 'ROWRE_TROPHY'; + public static TEASER: string = 'ROWRE_TEASER'; + public static ECOTRONBOX: string = 'ROWRE_ECOTRONBOX'; + public static DIMMER: string = 'ROWRE_DIMMER'; + public static WIDGET_REMOVE_DIMMER: string = 'ROWRE_WIDGET_REMOVE_DIMMER'; + public static CLOTHING_CHANGE: string = 'ROWRE_CLOTHING_CHANGE'; + public static JUKEBOX_PLAYLIST_EDITOR: string = 'ROWRE_JUKEBOX_PLAYLIST_EDITOR'; + public static MANNEQUIN: string = 'ROWRE_MANNEQUIN'; + public static PET_PRODUCT_MENU: string = 'ROWRE_PET_PRODUCT_MENU'; + public static GUILD_FURNI_CONTEXT_MENU: string = 'ROWRE_GUILD_FURNI_CONTEXT_MENU'; + public static MONSTERPLANT_SEED_PLANT_CONFIRMATION_DIALOG: string = 'ROWRE_MONSTERPLANT_SEED_PLANT_CONFIRMATION_DIALOG'; + public static PURCHASABLE_CLOTHING_CONFIRMATION_DIALOG: string = 'ROWRE_PURCHASABLE_CLOTHING_CONFIRMATION_DIALOG'; + public static BACKGROUND_COLOR: string = 'ROWRE_BACKGROUND_COLOR'; + public static MYSTERYBOX_OPEN_DIALOG: string = 'ROWRE_MYSTERYBOX_OPEN_DIALOG'; + public static EFFECTBOX_OPEN_DIALOG: string = 'ROWRE_EFFECTBOX_OPEN_DIALOG'; + public static MYSTERYTROPHY_OPEN_DIALOG: string = 'ROWRE_MYSTERYTROPHY_OPEN_DIALOG'; + public static ACHIEVEMENT_RESOLUTION_OPEN: string = 'ROWRE_ACHIEVEMENT_RESOLUTION_OPEN'; + public static ACHIEVEMENT_RESOLUTION_ENGRAVING: string = 'ROWRE_ACHIEVEMENT_RESOLUTION_ENGRAVING'; + public static ACHIEVEMENT_RESOLUTION_FAILED: string = 'ROWRE_ACHIEVEMENT_RESOLUTION_FAILED'; + public static FRIEND_FURNITURE_CONFIRM: string = 'ROWRE_FRIEND_FURNITURE_CONFIRM'; + public static FRIEND_FURNITURE_ENGRAVING: string = 'ROWRE_FRIEND_FURNITURE_ENGRAVING'; + public static BADGE_DISPLAY_ENGRAVING: string = 'ROWRE_BADGE_DISPLAY_ENGRAVING'; + public static HIGH_SCORE_DISPLAY: string = 'ROWRE_HIGH_SCORE_DISPLAY'; + public static HIDE_HIGH_SCORE_DISPLAY: string = 'ROWRE_HIDE_HIGH_SCORE_DISPLAY'; + public static INERNAL_LINK: string = 'ROWRE_INTERNAL_LINK'; + public static ROOM_LINK: string = 'ROWRE_ROOM_LINK'; + + constructor(k: string, _arg_2: IRoomObject) + { + super(k, _arg_2); + } +} \ No newline at end of file diff --git a/src/nitro/room/events/RoomToObjectOwnAvatarMoveEvent.ts b/src/nitro/room/events/RoomToObjectOwnAvatarMoveEvent.ts new file mode 100644 index 00000000..5f5da18f --- /dev/null +++ b/src/nitro/room/events/RoomToObjectOwnAvatarMoveEvent.ts @@ -0,0 +1,21 @@ +import { RoomToObjectEvent } from '../../../room/events/RoomToObjectEvent'; +import { IVector3D } from '../../../room/utils/IVector3D'; + +export class RoomToObjectOwnAvatarMoveEvent extends RoomToObjectEvent +{ + public static ROAME_MOVE_TO: string = 'ROAME_MOVE_TO'; + + private _targetLocation: IVector3D; + + constructor(type: string, targetLocation: IVector3D) + { + super(type); + + this._targetLocation = targetLocation; + } + + public get targetLocation(): IVector3D + { + return this._targetLocation; + } +} \ No newline at end of file diff --git a/src/nitro/room/events/RoomZoomEvent.ts b/src/nitro/room/events/RoomZoomEvent.ts new file mode 100644 index 00000000..caa4fc8c --- /dev/null +++ b/src/nitro/room/events/RoomZoomEvent.ts @@ -0,0 +1,34 @@ +import { RoomEngineEvent } from './RoomEngineEvent'; + +export class RoomZoomEvent extends RoomEngineEvent +{ + public static ROOM_ZOOM: string = 'REE_ROOM_ZOOM'; + + private _level: number; + private _forceFlip: boolean; + private _asDelta: boolean; + + constructor(roomId: number, level: number, forceFlip: boolean = false, asDelta: boolean = false) + { + super(RoomZoomEvent.ROOM_ZOOM, roomId); + + this._level = level; + this._forceFlip = forceFlip; + this._asDelta = asDelta; + } + + public get level(): number + { + return this._level; + } + + public get forceFlip(): boolean + { + return this._forceFlip; + } + + public get asDelta(): boolean + { + return this._asDelta; + } +} \ No newline at end of file diff --git a/src/nitro/room/messages/ObjectAdUpdateMessage.ts b/src/nitro/room/messages/ObjectAdUpdateMessage.ts new file mode 100644 index 00000000..537796ab --- /dev/null +++ b/src/nitro/room/messages/ObjectAdUpdateMessage.ts @@ -0,0 +1,21 @@ +import { RoomObjectUpdateMessage } from '../../../room/messages/RoomObjectUpdateMessage'; + +export class ObjectAdUpdateMessage extends RoomObjectUpdateMessage +{ + public static IMAGE_LOADED: string = 'ROAUM_IMAGE_LOADED'; + public static IMAGE_LOADING_FAILED: string = 'ROAUM_IMAGE_FAILED'; + + private _type: string; + + constructor(type: string) + { + super(null, null); + + this._type = type; + } + + public get type(): string + { + return this._type; + } +} \ No newline at end of file diff --git a/src/nitro/room/messages/ObjectAvatarCarryObjectUpdateMessage.ts b/src/nitro/room/messages/ObjectAvatarCarryObjectUpdateMessage.ts new file mode 100644 index 00000000..7c39d8f1 --- /dev/null +++ b/src/nitro/room/messages/ObjectAvatarCarryObjectUpdateMessage.ts @@ -0,0 +1,25 @@ +import { ObjectStateUpdateMessage } from './ObjectStateUpdateMessage'; + +export class ObjectAvatarCarryObjectUpdateMessage extends ObjectStateUpdateMessage +{ + private _itemType: number; + private _itemName: string; + + constructor(itemType: number, itemName: string) + { + super(); + + this._itemType = itemType; + this._itemName = itemName; + } + + public get itemType(): number + { + return this._itemType; + } + + public get itemName(): string + { + return this._itemName; + } +} \ No newline at end of file diff --git a/src/nitro/room/messages/ObjectAvatarChatUpdateMessage.ts b/src/nitro/room/messages/ObjectAvatarChatUpdateMessage.ts new file mode 100644 index 00000000..91b98340 --- /dev/null +++ b/src/nitro/room/messages/ObjectAvatarChatUpdateMessage.ts @@ -0,0 +1,18 @@ +import { ObjectStateUpdateMessage } from './ObjectStateUpdateMessage'; + +export class ObjectAvatarChatUpdateMessage extends ObjectStateUpdateMessage +{ + private _numberOfWords: number; + + constructor(numberOfWords: number = 0) + { + super(); + + this._numberOfWords = numberOfWords; + } + + public get numberOfWords(): number + { + return this._numberOfWords; + } +} \ No newline at end of file diff --git a/src/nitro/room/messages/ObjectAvatarDanceUpdateMessage.ts b/src/nitro/room/messages/ObjectAvatarDanceUpdateMessage.ts new file mode 100644 index 00000000..395739f5 --- /dev/null +++ b/src/nitro/room/messages/ObjectAvatarDanceUpdateMessage.ts @@ -0,0 +1,18 @@ +import { ObjectStateUpdateMessage } from './ObjectStateUpdateMessage'; + +export class ObjectAvatarDanceUpdateMessage extends ObjectStateUpdateMessage +{ + private _danceStyle: number; + + constructor(danceStyle: number = 0) + { + super(); + + this._danceStyle = danceStyle; + } + + public get danceStyle(): number + { + return this._danceStyle; + } +} \ No newline at end of file diff --git a/src/nitro/room/messages/ObjectAvatarEffectUpdateMessage.ts b/src/nitro/room/messages/ObjectAvatarEffectUpdateMessage.ts new file mode 100644 index 00000000..bed13e1c --- /dev/null +++ b/src/nitro/room/messages/ObjectAvatarEffectUpdateMessage.ts @@ -0,0 +1,25 @@ +import { ObjectStateUpdateMessage } from './ObjectStateUpdateMessage'; + +export class ObjectAvatarEffectUpdateMessage extends ObjectStateUpdateMessage +{ + private _effect: number; + private _delayMilliseconds: number; + + constructor(effect: number, delayMilliseconds: number = 0) + { + super(); + + this._effect = effect; + this._delayMilliseconds = delayMilliseconds; + } + + public get effect(): number + { + return this._effect; + } + + public get delayMilliseconds(): number + { + return this._delayMilliseconds; + } +} \ No newline at end of file diff --git a/src/nitro/room/messages/ObjectAvatarExperienceUpdateMessage.ts b/src/nitro/room/messages/ObjectAvatarExperienceUpdateMessage.ts new file mode 100644 index 00000000..ba082a97 --- /dev/null +++ b/src/nitro/room/messages/ObjectAvatarExperienceUpdateMessage.ts @@ -0,0 +1,18 @@ +import { ObjectStateUpdateMessage } from './ObjectStateUpdateMessage'; + +export class ObjectAvatarExperienceUpdateMessage extends ObjectStateUpdateMessage +{ + private _gainedExperience: number; + + constructor(amount: number) + { + super(); + + this._gainedExperience = amount; + } + + public get gainedExperience(): number + { + return this._gainedExperience; + } +} \ No newline at end of file diff --git a/src/nitro/room/messages/ObjectAvatarExpressionUpdateMessage.ts b/src/nitro/room/messages/ObjectAvatarExpressionUpdateMessage.ts new file mode 100644 index 00000000..8a33d150 --- /dev/null +++ b/src/nitro/room/messages/ObjectAvatarExpressionUpdateMessage.ts @@ -0,0 +1,18 @@ +import { ObjectStateUpdateMessage } from './ObjectStateUpdateMessage'; + +export class ObjectAvatarExpressionUpdateMessage extends ObjectStateUpdateMessage +{ + private _expressionType: number; + + constructor(expressionType: number = 0) + { + super(); + + this._expressionType = expressionType; + } + + public get expressionType(): number + { + return this._expressionType; + } +} \ No newline at end of file diff --git a/src/nitro/room/messages/ObjectAvatarFigureUpdateMessage.ts b/src/nitro/room/messages/ObjectAvatarFigureUpdateMessage.ts new file mode 100644 index 00000000..0abe10db --- /dev/null +++ b/src/nitro/room/messages/ObjectAvatarFigureUpdateMessage.ts @@ -0,0 +1,39 @@ +import { ObjectStateUpdateMessage } from './ObjectStateUpdateMessage'; + +export class ObjectAvatarFigureUpdateMessage extends ObjectStateUpdateMessage +{ + private _figure: string; + private _gender: string; + private _subType: string; + private _isRiding: boolean; + + constructor(figure: string, gender: string = null, subType: string = null, isRiding: boolean = false) + { + super(); + + this._figure = figure; + this._gender = gender; + this._subType = subType; + this._isRiding = isRiding; + } + + public get figure(): string + { + return this._figure; + } + + public get gender(): string + { + return this._gender; + } + + public get subType(): string + { + return this._subType; + } + + public get isRiding(): boolean + { + return this._isRiding; + } +} \ No newline at end of file diff --git a/src/nitro/room/messages/ObjectAvatarFlatControlUpdateMessage.ts b/src/nitro/room/messages/ObjectAvatarFlatControlUpdateMessage.ts new file mode 100644 index 00000000..51344887 --- /dev/null +++ b/src/nitro/room/messages/ObjectAvatarFlatControlUpdateMessage.ts @@ -0,0 +1,18 @@ +import { ObjectStateUpdateMessage } from './ObjectStateUpdateMessage'; + +export class ObjectAvatarFlatControlUpdateMessage extends ObjectStateUpdateMessage +{ + private _level: number; + + constructor(level: number = 0) + { + super(); + + this._level = level; + } + + public get level(): number + { + return this._level; + } +} \ No newline at end of file diff --git a/src/nitro/room/messages/ObjectAvatarGestureUpdateMessage.ts b/src/nitro/room/messages/ObjectAvatarGestureUpdateMessage.ts new file mode 100644 index 00000000..ad810f8e --- /dev/null +++ b/src/nitro/room/messages/ObjectAvatarGestureUpdateMessage.ts @@ -0,0 +1,18 @@ +import { ObjectStateUpdateMessage } from './ObjectStateUpdateMessage'; + +export class ObjectAvatarGestureUpdateMessage extends ObjectStateUpdateMessage +{ + private _gesture: number; + + constructor(gesture: number = 0) + { + super(); + + this._gesture = gesture; + } + + public get gesture(): number + { + return this._gesture; + } +} \ No newline at end of file diff --git a/src/nitro/room/messages/ObjectAvatarGuideStatusUpdateMessage.ts b/src/nitro/room/messages/ObjectAvatarGuideStatusUpdateMessage.ts new file mode 100644 index 00000000..bf5bd047 --- /dev/null +++ b/src/nitro/room/messages/ObjectAvatarGuideStatusUpdateMessage.ts @@ -0,0 +1,18 @@ +import { ObjectStateUpdateMessage } from './ObjectStateUpdateMessage'; + +export class ObjectAvatarGuideStatusUpdateMessage extends ObjectStateUpdateMessage +{ + private _guideStatus: number; + + constructor(value: number) + { + super(); + + this._guideStatus = value; + } + + public get guideStatus(): number + { + return this._guideStatus; + } +} \ No newline at end of file diff --git a/src/nitro/room/messages/ObjectAvatarMutedUpdateMessage.ts b/src/nitro/room/messages/ObjectAvatarMutedUpdateMessage.ts new file mode 100644 index 00000000..548aa160 --- /dev/null +++ b/src/nitro/room/messages/ObjectAvatarMutedUpdateMessage.ts @@ -0,0 +1,18 @@ +import { ObjectStateUpdateMessage } from './ObjectStateUpdateMessage'; + +export class ObjectAvatarMutedUpdateMessage extends ObjectStateUpdateMessage +{ + private _isMuted: boolean; + + constructor(isMuted: boolean = false) + { + super(); + + this._isMuted = isMuted; + } + + public get isMuted(): boolean + { + return this._isMuted; + } +} \ No newline at end of file diff --git a/src/nitro/room/messages/ObjectAvatarOwnMessage.ts b/src/nitro/room/messages/ObjectAvatarOwnMessage.ts new file mode 100644 index 00000000..cbdeeaf4 --- /dev/null +++ b/src/nitro/room/messages/ObjectAvatarOwnMessage.ts @@ -0,0 +1,4 @@ +import { ObjectStateUpdateMessage } from './ObjectStateUpdateMessage'; + +export class ObjectAvatarOwnMessage extends ObjectStateUpdateMessage +{} \ No newline at end of file diff --git a/src/nitro/room/messages/ObjectAvatarPetGestureUpdateMessage.ts b/src/nitro/room/messages/ObjectAvatarPetGestureUpdateMessage.ts new file mode 100644 index 00000000..c4f52daa --- /dev/null +++ b/src/nitro/room/messages/ObjectAvatarPetGestureUpdateMessage.ts @@ -0,0 +1,18 @@ +import { ObjectStateUpdateMessage } from './ObjectStateUpdateMessage'; + +export class ObjectAvatarPetGestureUpdateMessage extends ObjectStateUpdateMessage +{ + private _gesture: string; + + constructor(gesture: string) + { + super(); + + this._gesture = gesture; + } + + public get gesture(): string + { + return this._gesture; + } +} \ No newline at end of file diff --git a/src/nitro/room/messages/ObjectAvatarPlayerValueUpdateMessage.ts b/src/nitro/room/messages/ObjectAvatarPlayerValueUpdateMessage.ts new file mode 100644 index 00000000..af74ee00 --- /dev/null +++ b/src/nitro/room/messages/ObjectAvatarPlayerValueUpdateMessage.ts @@ -0,0 +1,18 @@ +import { ObjectStateUpdateMessage } from './ObjectStateUpdateMessage'; + +export class ObjectAvatarPlayerValueUpdateMessage extends ObjectStateUpdateMessage +{ + private _value: number; + + constructor(value: number) + { + super(); + + this._value = value; + } + + public get value(): number + { + return this._value; + } +} \ No newline at end of file diff --git a/src/nitro/room/messages/ObjectAvatarPlayingGameUpdateMessage.ts b/src/nitro/room/messages/ObjectAvatarPlayingGameUpdateMessage.ts new file mode 100644 index 00000000..d18ff82c --- /dev/null +++ b/src/nitro/room/messages/ObjectAvatarPlayingGameUpdateMessage.ts @@ -0,0 +1,18 @@ +import { ObjectStateUpdateMessage } from './ObjectStateUpdateMessage'; + +export class ObjectAvatarPlayingGameUpdateMessage extends ObjectStateUpdateMessage +{ + private _isPlayingGame: boolean; + + constructor(flag: boolean) + { + super(); + + this._isPlayingGame = flag; + } + + public get isPlayingGame(): boolean + { + return this._isPlayingGame; + } +} \ No newline at end of file diff --git a/src/nitro/room/messages/ObjectAvatarPostureUpdateMessage.ts b/src/nitro/room/messages/ObjectAvatarPostureUpdateMessage.ts new file mode 100644 index 00000000..008b3f6b --- /dev/null +++ b/src/nitro/room/messages/ObjectAvatarPostureUpdateMessage.ts @@ -0,0 +1,25 @@ +import { ObjectStateUpdateMessage } from './ObjectStateUpdateMessage'; + +export class ObjectAvatarPostureUpdateMessage extends ObjectStateUpdateMessage +{ + private _postureType: string; + private _parameter: string; + + constructor(postureType: string, parameter: string = '') + { + super(); + + this._postureType = postureType; + this._parameter = parameter; + } + + public get postureType(): string + { + return this._postureType; + } + + public get parameter(): string + { + return this._parameter; + } +} \ No newline at end of file diff --git a/src/nitro/room/messages/ObjectAvatarSelectedMessage.ts b/src/nitro/room/messages/ObjectAvatarSelectedMessage.ts new file mode 100644 index 00000000..dc7ac65c --- /dev/null +++ b/src/nitro/room/messages/ObjectAvatarSelectedMessage.ts @@ -0,0 +1,18 @@ +import { ObjectStateUpdateMessage } from './ObjectStateUpdateMessage'; + +export class ObjectAvatarSelectedMessage extends ObjectStateUpdateMessage +{ + private _selected: boolean; + + constructor(selected: boolean) + { + super(); + + this._selected = selected; + } + + public get selected(): boolean + { + return this._selected; + } +} \ No newline at end of file diff --git a/src/nitro/room/messages/ObjectAvatarSignUpdateMessage.ts b/src/nitro/room/messages/ObjectAvatarSignUpdateMessage.ts new file mode 100644 index 00000000..bfb63b8d --- /dev/null +++ b/src/nitro/room/messages/ObjectAvatarSignUpdateMessage.ts @@ -0,0 +1,18 @@ +import { ObjectStateUpdateMessage } from './ObjectStateUpdateMessage'; + +export class ObjectAvatarSignUpdateMessage extends ObjectStateUpdateMessage +{ + private _signType: number; + + constructor(signType: number = 0) + { + super(); + + this._signType = signType; + } + + public get signType(): number + { + return this._signType; + } +} \ No newline at end of file diff --git a/src/nitro/room/messages/ObjectAvatarSleepUpdateMessage.ts b/src/nitro/room/messages/ObjectAvatarSleepUpdateMessage.ts new file mode 100644 index 00000000..747fd13e --- /dev/null +++ b/src/nitro/room/messages/ObjectAvatarSleepUpdateMessage.ts @@ -0,0 +1,18 @@ +import { ObjectStateUpdateMessage } from './ObjectStateUpdateMessage'; + +export class ObjectAvatarSleepUpdateMessage extends ObjectStateUpdateMessage +{ + private _isSleeping: boolean; + + constructor(isSleeping: boolean = false) + { + super(); + + this._isSleeping = isSleeping; + } + + public get isSleeping(): boolean + { + return this._isSleeping; + } +} \ No newline at end of file diff --git a/src/nitro/room/messages/ObjectAvatarTypingUpdateMessage.ts b/src/nitro/room/messages/ObjectAvatarTypingUpdateMessage.ts new file mode 100644 index 00000000..0038f76b --- /dev/null +++ b/src/nitro/room/messages/ObjectAvatarTypingUpdateMessage.ts @@ -0,0 +1,18 @@ +import { ObjectStateUpdateMessage } from './ObjectStateUpdateMessage'; + +export class ObjectAvatarTypingUpdateMessage extends ObjectStateUpdateMessage +{ + private _isTyping: boolean; + + constructor(isTyping: boolean = false) + { + super(); + + this._isTyping = isTyping; + } + + public get isTyping(): boolean + { + return this._isTyping; + } +} \ No newline at end of file diff --git a/src/nitro/room/messages/ObjectAvatarUpdateMessage.ts b/src/nitro/room/messages/ObjectAvatarUpdateMessage.ts new file mode 100644 index 00000000..4b255a2c --- /dev/null +++ b/src/nitro/room/messages/ObjectAvatarUpdateMessage.ts @@ -0,0 +1,33 @@ +import { IVector3D } from '../../../room/utils/IVector3D'; +import { ObjectMoveUpdateMessage } from './ObjectMoveUpdateMessage'; + +export class ObjectAvatarUpdateMessage extends ObjectMoveUpdateMessage +{ + private _headDirection: number; + private _canStandUp: boolean; + private _baseY: number; + + constructor(location: IVector3D, targetLocation: IVector3D, direction: IVector3D, headDirection: number, canStandUp: boolean, baseY: number) + { + super(location, targetLocation, direction); + + this._headDirection = headDirection; + this._canStandUp = canStandUp; + this._baseY = baseY; + } + + public get headDirection(): number + { + return this._headDirection; + } + + public get canStandUp(): boolean + { + return this._canStandUp; + } + + public get baseY(): number + { + return this._baseY; + } +} \ No newline at end of file diff --git a/src/nitro/room/messages/ObjectAvatarUseObjectUpdateMessage.ts b/src/nitro/room/messages/ObjectAvatarUseObjectUpdateMessage.ts new file mode 100644 index 00000000..6997a70b --- /dev/null +++ b/src/nitro/room/messages/ObjectAvatarUseObjectUpdateMessage.ts @@ -0,0 +1,18 @@ +import { ObjectStateUpdateMessage } from './ObjectStateUpdateMessage'; + +export class ObjectAvatarUseObjectUpdateMessage extends ObjectStateUpdateMessage +{ + private _itemType: number; + + constructor(itemType: number) + { + super(); + + this._itemType = itemType; + } + + public get itemType(): number + { + return this._itemType; + } +} \ No newline at end of file diff --git a/src/nitro/room/messages/ObjectDataUpdateMessage.ts b/src/nitro/room/messages/ObjectDataUpdateMessage.ts new file mode 100644 index 00000000..01e23e77 --- /dev/null +++ b/src/nitro/room/messages/ObjectDataUpdateMessage.ts @@ -0,0 +1,33 @@ +import { RoomObjectUpdateMessage } from '../../../room/messages/RoomObjectUpdateMessage'; +import { IObjectData } from '../object/data/IObjectData'; + +export class ObjectDataUpdateMessage extends RoomObjectUpdateMessage +{ + private _state: number; + private _data: IObjectData; + private _extra: number; + + constructor(state: number, data: IObjectData, extra: number = NaN) + { + super(null, null); + + this._state = state; + this._data = data; + this._extra = extra; + } + + public get state(): number + { + return this._state; + } + + public get data(): IObjectData + { + return this._data; + } + + public get extra(): number + { + return this._extra; + } +} \ No newline at end of file diff --git a/src/nitro/room/messages/ObjectGroupBadgeUpdateMessage.ts b/src/nitro/room/messages/ObjectGroupBadgeUpdateMessage.ts new file mode 100644 index 00000000..8c66a2b1 --- /dev/null +++ b/src/nitro/room/messages/ObjectGroupBadgeUpdateMessage.ts @@ -0,0 +1,27 @@ +import { RoomObjectUpdateMessage } from '../../../room/messages/RoomObjectUpdateMessage'; + +export class ObjectGroupBadgeUpdateMessage extends RoomObjectUpdateMessage +{ + public static BADGE_LOADED: string = 'ROGBUM_BADGE_LOADED'; + + private _badgeId: string; + private _assetName: string; + + constructor(badgeId: string, assetName: string) + { + super(null, null); + + this._badgeId = badgeId; + this._assetName = assetName; + } + + public get badgeId(): string + { + return this._badgeId; + } + + public get assetName(): string + { + return this._assetName; + } +} \ No newline at end of file diff --git a/src/nitro/room/messages/ObjectHeightUpdateMessage.ts b/src/nitro/room/messages/ObjectHeightUpdateMessage.ts new file mode 100644 index 00000000..46c8a1b8 --- /dev/null +++ b/src/nitro/room/messages/ObjectHeightUpdateMessage.ts @@ -0,0 +1,19 @@ +import { RoomObjectUpdateMessage } from '../../../room/messages/RoomObjectUpdateMessage'; +import { IVector3D } from '../../../room/utils/IVector3D'; + +export class ObjectHeightUpdateMessage extends RoomObjectUpdateMessage +{ + private _height: number; + + constructor(location: IVector3D, direction: IVector3D, height: number) + { + super(location, direction); + + this._height = height; + } + + public get height(): number + { + return this._height; + } +} \ No newline at end of file diff --git a/src/nitro/room/messages/ObjectItemDataUpdateMessage.ts b/src/nitro/room/messages/ObjectItemDataUpdateMessage.ts new file mode 100644 index 00000000..ddf492b8 --- /dev/null +++ b/src/nitro/room/messages/ObjectItemDataUpdateMessage.ts @@ -0,0 +1,18 @@ +import { RoomObjectUpdateMessage } from '../../../room/messages/RoomObjectUpdateMessage'; + +export class ObjectItemDataUpdateMessage extends RoomObjectUpdateMessage +{ + private _data: string; + + constructor(data: string) + { + super(null, null); + + this._data = data; + } + + public get data(): string + { + return this._data; + } +} \ No newline at end of file diff --git a/src/nitro/room/messages/ObjectModelDataUpdateMessage.ts b/src/nitro/room/messages/ObjectModelDataUpdateMessage.ts new file mode 100644 index 00000000..dbcd4a47 --- /dev/null +++ b/src/nitro/room/messages/ObjectModelDataUpdateMessage.ts @@ -0,0 +1,25 @@ +import { RoomObjectUpdateMessage } from '../../../room/messages/RoomObjectUpdateMessage'; + +export class ObjectModelDataUpdateMessage extends RoomObjectUpdateMessage +{ + private _numberKey: string; + private _numberValue:number; + + constructor(numberKey: string, numberValue: number) + { + super(null, null); + + this._numberKey = numberKey; + this._numberValue = numberValue; + } + + public get numberKey(): string + { + return this._numberKey; + } + + public get numberValue(): number + { + return this._numberValue; + } +} diff --git a/src/nitro/room/messages/ObjectMoveUpdateMessage.ts b/src/nitro/room/messages/ObjectMoveUpdateMessage.ts new file mode 100644 index 00000000..d0f6efdf --- /dev/null +++ b/src/nitro/room/messages/ObjectMoveUpdateMessage.ts @@ -0,0 +1,28 @@ +import { RoomObjectUpdateMessage } from '../../../room/messages/RoomObjectUpdateMessage'; +import { IVector3D } from '../../../room/utils/IVector3D'; + +export class ObjectMoveUpdateMessage extends RoomObjectUpdateMessage +{ + private _targetLocation: IVector3D; + private _isSlide: boolean; + + constructor(location: IVector3D, targetLocation: IVector3D, direction: IVector3D, isSlide: boolean = false) + { + super(location, direction); + + this._targetLocation = targetLocation; + this._isSlide = isSlide; + } + + public get targetLocation(): IVector3D + { + if(!this._targetLocation) return this.location; + + return this._targetLocation; + } + + public get isSlide(): boolean + { + return this._isSlide; + } +} \ No newline at end of file diff --git a/src/nitro/room/messages/ObjectRoomColorUpdateMessage.ts b/src/nitro/room/messages/ObjectRoomColorUpdateMessage.ts new file mode 100644 index 00000000..6b6ca3a4 --- /dev/null +++ b/src/nitro/room/messages/ObjectRoomColorUpdateMessage.ts @@ -0,0 +1,41 @@ +import { RoomObjectUpdateMessage } from '../../../room/messages/RoomObjectUpdateMessage'; + +export class ObjectRoomColorUpdateMessage extends RoomObjectUpdateMessage +{ + public static BACKGROUND_COLOR: string = 'RORCUM_BACKGROUND_COLOR'; + + private _type: string; + private _color: number; + private _light: number; + private _backgroundOnly: boolean; + + constructor(type: string, color: number, light: number, backgroundOnly: boolean) + { + super(null, null); + + this._type = type; + this._color = color; + this._light = light; + this._backgroundOnly = backgroundOnly; + } + + public get type(): string + { + return this._type; + } + + public get color(): number + { + return this._color; + } + + public get light(): number + { + return this._light; + } + + public get backgroundOnly(): boolean + { + return this._backgroundOnly; + } +} \ No newline at end of file diff --git a/src/nitro/room/messages/ObjectRoomFloorHoleUpdateMessage.ts b/src/nitro/room/messages/ObjectRoomFloorHoleUpdateMessage.ts new file mode 100644 index 00000000..da287088 --- /dev/null +++ b/src/nitro/room/messages/ObjectRoomFloorHoleUpdateMessage.ts @@ -0,0 +1,56 @@ +import { RoomObjectUpdateMessage } from '../../../room/messages/RoomObjectUpdateMessage'; + +export class ObjectRoomFloorHoleUpdateMessage extends RoomObjectUpdateMessage +{ + public static ADD: string = 'ORPFHUM_ADD'; + public static REMOVE: string = 'ORPFHUM_REMOVE'; + + private _type: string; + private _id: number; + private _x: number; + private _y: number; + private _width: number; + private _height: number; + + constructor(type: string, id: number, x: number = 0, y: number = 0, width: number = 0, height: number = 0) + { + super(null, null); + + this._type = type; + this._id = id; + this._x = x; + this._y = y; + this._width = width; + this._height = height; + } + + public get type(): string + { + return this._type; + } + + public get id(): number + { + return this._id; + } + + public get x(): number + { + return this._x; + } + + public get y(): number + { + return this._y; + } + + public get width(): number + { + return this._width; + } + + public get height(): number + { + return this._height; + } +} \ No newline at end of file diff --git a/src/nitro/room/messages/ObjectRoomMapUpdateMessage.ts b/src/nitro/room/messages/ObjectRoomMapUpdateMessage.ts new file mode 100644 index 00000000..31d1d011 --- /dev/null +++ b/src/nitro/room/messages/ObjectRoomMapUpdateMessage.ts @@ -0,0 +1,28 @@ +import { RoomObjectUpdateMessage } from '../../../room/messages/RoomObjectUpdateMessage'; +import { RoomMapData } from '../object/RoomMapData'; + +export class ObjectRoomMapUpdateMessage extends RoomObjectUpdateMessage +{ + public static UPDATE_MAP: string = 'RORMUM_UPDATE_MAP'; + + private _type: string; + private _mapData: RoomMapData; + + constructor(mapData: RoomMapData) + { + super(null, null); + + this._type = ObjectRoomMapUpdateMessage.UPDATE_MAP; + this._mapData = mapData; + } + + public get type(): string + { + return this._type; + } + + public get mapData(): RoomMapData + { + return this._mapData; + } +} diff --git a/src/nitro/room/messages/ObjectRoomMaskUpdateMessage.ts b/src/nitro/room/messages/ObjectRoomMaskUpdateMessage.ts new file mode 100644 index 00000000..a26eef4d --- /dev/null +++ b/src/nitro/room/messages/ObjectRoomMaskUpdateMessage.ts @@ -0,0 +1,54 @@ +import { RoomObjectUpdateMessage } from '../../../room/messages/RoomObjectUpdateMessage'; +import { IVector3D } from '../../../room/utils/IVector3D'; +import { Vector3d } from '../../../room/utils/Vector3d'; + +export class ObjectRoomMaskUpdateMessage extends RoomObjectUpdateMessage +{ + public static ADD_MASK: string = 'RORMUM_ADD_MASK'; + public static _Str_10260: string = 'RORMUM_ADD_MASK'; + public static DOOR: string = 'door'; + public static WINDOW: string = 'window'; + public static HOLE: string = 'hole'; + + private _type: string; + private _maskId: string; + private _maskType: string; + private _maskLocation: Vector3d; + private _maskCategory: string; + + constructor(type: string, maskId: string, maskType: string = null, maskLocation: IVector3D = null, maskCategory: string = 'window') + { + super(null, null); + + this._type = type; + this._maskId = maskId; + this._maskType = maskType; + this._maskLocation = maskLocation ? new Vector3d(maskLocation.x, maskLocation.y, maskLocation.z) : null; + this._maskCategory = maskCategory; + } + + public get type(): string + { + return this._type; + } + + public get maskId(): string + { + return this._maskId; + } + + public get maskType(): string + { + return this._maskType; + } + + public get maskLocation(): IVector3D + { + return this._maskLocation; + } + + public get maskCategory(): string + { + return this._maskCategory; + } +} \ No newline at end of file diff --git a/src/nitro/room/messages/ObjectRoomPlanePropertyUpdateMessage.ts b/src/nitro/room/messages/ObjectRoomPlanePropertyUpdateMessage.ts new file mode 100644 index 00000000..e842baf5 --- /dev/null +++ b/src/nitro/room/messages/ObjectRoomPlanePropertyUpdateMessage.ts @@ -0,0 +1,28 @@ +import { RoomObjectUpdateMessage } from '../../../room/messages/RoomObjectUpdateMessage'; + +export class ObjectRoomPlanePropertyUpdateMessage extends RoomObjectUpdateMessage +{ + public static WALL_THICKNESS: string = 'RORPPUM_WALL_THICKNESS'; + public static FLOOR_THICKNESS: string = 'RORPVUM_FLOOR_THICKNESS'; + + private _type: string; + private _value: number; + + constructor(type: string, value: number) + { + super(null, null); + + this._type = type; + this._value = value; + } + + public get type(): string + { + return this._type; + } + + public get value(): number + { + return this._value; + } +} \ No newline at end of file diff --git a/src/nitro/room/messages/ObjectRoomPlaneVisibilityUpdateMessage.ts b/src/nitro/room/messages/ObjectRoomPlaneVisibilityUpdateMessage.ts new file mode 100644 index 00000000..5c91640d --- /dev/null +++ b/src/nitro/room/messages/ObjectRoomPlaneVisibilityUpdateMessage.ts @@ -0,0 +1,28 @@ +import { RoomObjectUpdateMessage } from '../../../room/messages/RoomObjectUpdateMessage'; + +export class ObjectRoomPlaneVisibilityUpdateMessage extends RoomObjectUpdateMessage +{ + public static WALL_VISIBILITY: string = 'RORPVUM_WALL_VISIBILITY'; + public static FLOOR_VISIBILITY: string = 'RORPVUM_FLOOR_VISIBILITY'; + + private _type: string; + private _visible: boolean; + + constructor(type: string, visible: boolean) + { + super(null, null); + + this._type = type; + this._visible = visible; + } + + public get type(): string + { + return this._type; + } + + public get visible(): boolean + { + return this._visible; + } +} \ No newline at end of file diff --git a/src/nitro/room/messages/ObjectRoomUpdateMessage.ts b/src/nitro/room/messages/ObjectRoomUpdateMessage.ts new file mode 100644 index 00000000..6f871a60 --- /dev/null +++ b/src/nitro/room/messages/ObjectRoomUpdateMessage.ts @@ -0,0 +1,29 @@ +import { RoomObjectUpdateMessage } from '../../../room/messages/RoomObjectUpdateMessage'; + +export class ObjectRoomUpdateMessage extends RoomObjectUpdateMessage +{ + public static ROOM_WALL_UPDATE: string = 'RORUM_ROOM_WALL_UPDATE'; + public static ROOM_FLOOR_UPDATE: string = 'RORUM_ROOM_FLOOR_UPDATE'; + public static ROOM_LANDSCAPE_UPDATE: string = 'RORUM_ROOM_LANDSCAPE_UPDATE'; + + private _type: string; + private _value: string; + + constructor(type: string, value: string) + { + super(null, null); + + this._type = type; + this._value = value; + } + + public get type(): string + { + return this._type; + } + + public get value(): string + { + return this._value; + } +} \ No newline at end of file diff --git a/src/nitro/room/messages/ObjectSelectedMessage.ts b/src/nitro/room/messages/ObjectSelectedMessage.ts new file mode 100644 index 00000000..e807613e --- /dev/null +++ b/src/nitro/room/messages/ObjectSelectedMessage.ts @@ -0,0 +1,18 @@ +import { ObjectStateUpdateMessage } from './ObjectStateUpdateMessage'; + +export class ObjectSelectedMessage extends ObjectStateUpdateMessage +{ + private _selected: boolean; + + constructor(selected: boolean) + { + super(); + + this._selected = selected; + } + + public get selected(): boolean + { + return this._selected; + } +} \ No newline at end of file diff --git a/src/nitro/room/messages/ObjectStateUpdateMessage.ts b/src/nitro/room/messages/ObjectStateUpdateMessage.ts new file mode 100644 index 00000000..0bb7d4b0 --- /dev/null +++ b/src/nitro/room/messages/ObjectStateUpdateMessage.ts @@ -0,0 +1,9 @@ +import { RoomObjectUpdateMessage } from '../../../room/messages/RoomObjectUpdateMessage'; + +export class ObjectStateUpdateMessage extends RoomObjectUpdateMessage +{ + constructor() + { + super(null, null); + } +} \ No newline at end of file diff --git a/src/nitro/room/messages/ObjectTileCursorUpdateMessage.ts b/src/nitro/room/messages/ObjectTileCursorUpdateMessage.ts new file mode 100644 index 00000000..b9acab81 --- /dev/null +++ b/src/nitro/room/messages/ObjectTileCursorUpdateMessage.ts @@ -0,0 +1,40 @@ +import { RoomObjectUpdateMessage } from '../../../room/messages/RoomObjectUpdateMessage'; +import { Vector3d } from '../../../room/utils/Vector3d'; + +export class ObjectTileCursorUpdateMessage extends RoomObjectUpdateMessage +{ + private _height: number; + private _sourceEventId: string; + private _visible: boolean; + private _toggleVisibility: boolean; + + constructor(k: Vector3d, height: number, visible: boolean, sourceEventId: string, toggleVisibility: boolean = false) + { + super(k, null); + + this._height = height; + this._visible = visible; + this._sourceEventId = sourceEventId; + this._toggleVisibility = toggleVisibility; + } + + public get height(): number + { + return this._height; + } + + public get visible(): boolean + { + return this._visible; + } + + public get _Str_20637(): string + { + return this._sourceEventId; + } + + public get toggleVisibility(): boolean + { + return this._toggleVisibility; + } +} \ No newline at end of file diff --git a/src/nitro/room/messages/ObjectVisibilityUpdateMessage.ts b/src/nitro/room/messages/ObjectVisibilityUpdateMessage.ts new file mode 100644 index 00000000..1db1f5e9 --- /dev/null +++ b/src/nitro/room/messages/ObjectVisibilityUpdateMessage.ts @@ -0,0 +1,21 @@ +import { RoomObjectUpdateMessage } from '../../../room/messages/RoomObjectUpdateMessage'; + +export class ObjectVisibilityUpdateMessage extends RoomObjectUpdateMessage +{ + public static ENABLED: string = 'ROVUM_ENABLED'; + public static DISABLED: string = 'ROVUM_DISABLED'; + + private _type: string; + + constructor(type: string) + { + super(null, null); + + this._type = type; + } + + public get type(): string + { + return this._type; + } +} \ No newline at end of file diff --git a/src/nitro/room/object/RoomFloorHole.ts b/src/nitro/room/object/RoomFloorHole.ts new file mode 100644 index 00000000..456dfd53 --- /dev/null +++ b/src/nitro/room/object/RoomFloorHole.ts @@ -0,0 +1,35 @@ +export class RoomFloorHole +{ + private _x: number; + private _y: number; + private _width: number; + private _height: number; + + constructor(x: number, y: number, width: number, height: number) + { + this._x = x; + this._y = y; + this._width = width; + this._height = height; + } + + public get x(): number + { + return this._x; + } + + public get y(): number + { + return this._y; + } + + public get width(): number + { + return this._width; + } + + public get height(): number + { + return this._height; + } +} \ No newline at end of file diff --git a/src/nitro/room/object/RoomMapData.ts b/src/nitro/room/object/RoomMapData.ts new file mode 100644 index 00000000..1f9a83f0 --- /dev/null +++ b/src/nitro/room/object/RoomMapData.ts @@ -0,0 +1,125 @@ + +export class RoomMapData +{ + private _width: number; + private _height: number; + private _wallHeight: number; + private _fixedWallsHeight: number; + private _tileMap: { height: number }[][]; + private _holeMap: { id: number, x: number, y: number, width: number, height: number }[]; + private _doors: { x: number, y: number, z: number, dir: number }[]; + private _dimensions: { minX: number, maxX: number, minY: number, maxY: number }; + private _restrictsDragging: boolean; + private _restrictsScaling: boolean; + private _restrictedScale: number; + + constructor() + { + this._width = 0; + this._height = 0; + this._wallHeight = 0; + this._fixedWallsHeight = 0; + this._tileMap = []; + this._holeMap = []; + this._doors = []; + this._dimensions = { + minX: 0, + maxX: 0, + minY: 0, + maxY: 0 + }; + this._restrictsDragging = false; + this._restrictedScale = 1; + this._restrictsScaling = false; + } + + public get width(): number + { + return this._width; + } + + public set width(width: number) + { + this._width = width; + } + + public get height(): number + { + return this._height; + } + + public set height(height: number) + { + this._height = height; + } + + public get wallHeight(): number + { + return this._wallHeight; + } + + public set wallHeight(wallHeight: number) + { + this._wallHeight = wallHeight; + } + + public get fixedWallsHeight(): number + { + return this._fixedWallsHeight; + } + + public set fixedWallsHeight(fixedWallsHeight: number) + { + this._fixedWallsHeight = fixedWallsHeight; + } + + public get tileMap(): { height: number }[][] + { + return this._tileMap; + } + + public get holeMap(): { id: number, x: number, y: number, width: number, height: number }[] + { + return this._holeMap; + } + + public get doors(): { x: number, y: number, z: number, dir: number }[] + { + return this._doors; + } + + public get dimensions(): { minX: number, maxX: number, minY: number, maxY: number } + { + return this._dimensions; + } + + public get restrictsDragging(): boolean + { + return this._restrictsDragging; + } + + public set restrictsDragging(flag: boolean) + { + this._restrictsDragging = flag; + } + + public get restrictsScaling(): boolean + { + return this._restrictsScaling; + } + + public set restrictsScaling(flag: boolean) + { + this._restrictsScaling = flag; + } + + public get restrictedScale(): number + { + return this._restrictedScale; + } + + public set restrictedScale(scale: number) + { + this._restrictedScale = scale; + } +} \ No newline at end of file diff --git a/src/nitro/room/object/RoomMapMaskData.ts b/src/nitro/room/object/RoomMapMaskData.ts new file mode 100644 index 00000000..e823be67 --- /dev/null +++ b/src/nitro/room/object/RoomMapMaskData.ts @@ -0,0 +1,16 @@ +import { IVector3D } from '../../../room/utils/IVector3D'; + +export class RoomMapMaskData +{ + private _masks: { id: string, type: string, category: string, locations: IVector3D[] }[]; + + constructor() + { + this._masks = []; + } + + public get masks(): { id: string, type: string, category: string, locations: IVector3D[] }[] + { + return this._masks; + } +} \ No newline at end of file diff --git a/src/nitro/room/object/RoomObjectCategory.ts b/src/nitro/room/object/RoomObjectCategory.ts new file mode 100644 index 00000000..0acf6c46 --- /dev/null +++ b/src/nitro/room/object/RoomObjectCategory.ts @@ -0,0 +1,9 @@ +export class RoomObjectCategory +{ + public static MINIMUM: number = -2; + public static ROOM: number = 0; + public static FLOOR: number = 10; + public static WALL: number = 20; + public static UNIT: number = 100; + public static CURSOR: number = 200; +} \ No newline at end of file diff --git a/src/nitro/room/object/RoomObjectLogicType.ts b/src/nitro/room/object/RoomObjectLogicType.ts new file mode 100644 index 00000000..21024f42 --- /dev/null +++ b/src/nitro/room/object/RoomObjectLogicType.ts @@ -0,0 +1,74 @@ +export class RoomObjectLogicType +{ + public static FURNITURE_BASIC = 'furniture_basic'; + public static FURNITURE_MULTISTATE = 'furniture_multistate'; + public static FURNITURE_MULTIHEIGHT = 'furniture_multiheight'; + public static FURNITURE_RANDOMSTATE = 'furniture_randomstate'; + public static FURNITURE_PLACEHOLDER = 'furniture_placeholder'; + public static FURNITURE_CREDIT = 'furniture_credit'; + public static FURNITURE_STICKIE = 'furniture_stickie'; + public static FURNITURE_PRESENT = 'furniture_present'; + public static FURNITURE_TROPHY = 'furniture_trophy'; + public static FURNITURE_ECOTRON_BOX = 'furniture_ecotron_box'; + public static FURNITURE_DICE = 'furniture_dice'; + public static FURNITURE_HOCKEY_SCORE = 'furniture_hockey_score'; + public static FURNITURE_HABBOWHEEL = 'furniture_habbowheel'; + public static FURNITURE_ONE_WAY_DOOR = 'furniture_one_way_door'; + public static FURNITURE_PLANET_SYSTEM = 'furniture_planet_system'; + public static FURNITURE_WINDOW = 'furniture_window'; + public static FURNITURE_EXTERNAL_IMAGE_WALLITEM = 'furniture_external_image_wallitem'; + public static FURNITURE_ROOMDIMMER = 'furniture_roomdimmer'; + public static FURNITURE_SOUND_MACHINE = 'furniture_sound_machine'; + public static FURNITURE_JUKEBOX = 'furniture_jukebox'; + public static FURNITURE_CRACKABLE = 'furniture_crackable'; + public static FURNITURE_PUSHABLE = 'furniture_pushable'; + public static FURNITURE_CLOTHING_CHANGE = 'furniture_clothing_change'; + public static FURNITURE_COUNTER_CLOCK = 'furniture_counter_clock'; + public static FURNITURE_SCORE = 'furniture_score'; + public static FURNITURE_ES = 'furniture_es'; + public static FURNITURE_FIREWORKS = 'furniture_fireworks'; + public static FURNITURE_SONG_DISK = 'furniture_song_disk'; + public static FURNITURE_BB = 'furniture_bb'; + public static FURNITURE_BG = 'furniture_bg'; + public static FURNITURE_WELCOME_GIFT = 'furniture_welcome_gift'; + public static FURNITURE_FLOOR_HOLE = 'furniture_floor_hole'; + public static FURNITURE_MANNEQUIN = 'furniture_mannequin'; + public static FURNITURE_GUILD_CUSTOMIZED = 'furniture_guild_customized'; + public static FURNITURE_GROUP_FORUM_TERMINAL = 'furniture_group_forum_terminal'; + public static FURNITURE_PET_CUSTOMIZATION = 'furniture_pet_customization'; + public static FURNITURE_CUCKOO_CLOCK = 'furniture_cuckoo_clock'; + public static FURNITURE_VOTE_COUNTER = 'furniture_vote_counter'; + public static FURNITURE_VOTE_MAJORITY = 'furniture_vote_majority'; + public static FURNITURE_SOUNDBLOCK = 'furniture_soundblock'; + public static FURNITURE_RANDOM_TELEPORT = 'furniture_random_teleport'; + public static FURNITURE_MONSTERPLANT_SEED = 'furniture_monsterplant_seed'; + public static FURNITURE_PURCHASABLE_CLOTHING = 'furniture_purchasable_clothing'; + public static FURNITURE_BACKGROUND_COLOR = 'furniture_background_color'; + public static FURNITURE_MYSTERYBOX = 'furniture_mysterybox'; + public static FURNITURE_EFFECTBOX = 'furniture_effectbox'; + public static FURNITURE_MYSTERYTROPHY = 'furniture_mysterytrophy'; + public static FURNITURE_ACHIEVEMENT_RESOLUTION = 'furniture_achievement_resolution'; + public static FURNITURE_LOVELOCK = 'furniture_lovelock'; + public static FURNITURE_WILDWEST_WANTED = 'furniture_wildwest_wanted'; + public static FURNITURE_HWEEN_LOVELOCK = 'furniture_hween_lovelock'; + public static FURNITURE_BADGE_DISPLAY = 'furniture_badge_display'; + public static FURNITURE_HIGH_SCORE = 'furniture_high_score'; + public static FURNITURE_INTERNAL_LINK = 'furniture_internal_link'; + public static FURNITURE_CUSTOM_STACK_HEIGHT = 'furniture_custom_stack_height'; + public static FURNITURE_YOUTUBE = 'furniture_youtube'; + public static FURNITURE_RENTABLE_SPACE = 'furniture_rentable_space'; + public static FURNITURE_CHANGE_STATE_WHEN_STEP_ON = 'furniture_change_state_when_step_on'; + public static FURNITURE_VIMEO = 'furniture_vimeo'; + public static FURNITURE_EDITABLE_INTERNAL_LINK = 'furniture_editable_internal_link'; + public static FURNITURE_EDITABLE_ROOM_LINK = 'furniture_editable_room_link'; + public static FURNITURE_CRAFTING_GIZMO = 'furniture_crafting_gizmo'; + public static ROOM = 'room'; + public static USER = 'user'; + public static BOT = 'bot'; + public static RENTABLE_BOT = 'rentable_bot'; + public static PET = 'pet'; + public static TILE_CURSOR = 'tile_cursor'; + public static SELECTION_ARROW = 'selection_arrow'; + public static GAME_SNOWBALL = 'game_snowball'; + public static GAME_SNOWSPLASH = 'game_snowsplash'; +} \ No newline at end of file diff --git a/src/nitro/room/object/RoomObjectOperationType.ts b/src/nitro/room/object/RoomObjectOperationType.ts new file mode 100644 index 00000000..655d6092 --- /dev/null +++ b/src/nitro/room/object/RoomObjectOperationType.ts @@ -0,0 +1,15 @@ +export class RoomObjectOperationType +{ + public static OBJECT_UNDEFINED: string = 'OBJECT_UNDEFINED'; + public static OBJECT_MOVE: string = 'OBJECT_MOVE'; + public static OBJECT_PLACE: string = 'OBJECT_PLACE'; + public static OBJECT_ROTATE_POSITIVE: string = 'OBJECT_ROTATE_POSITIVE'; + public static OBJECT_ROTATE_NEGATIVE: string = 'OBJECT_ROTATE_NEGATIVE'; + public static OBJECT_MOVE_TO: string = 'OBJECT_MOVE_TO'; + public static OBJECT_PLACE_TO: string = 'OBJECT_PLACE_TO'; + public static OBJECT_PICKUP: string = 'OBJECT_PICKUP'; + public static OBJECT_PICKUP_BOT: string = 'OBJECT_PICKUP_BOT'; + public static OBJECT_PICKUP_PET: string = 'OBJECT_PICKUP_PET'; + public static OBJECT_EJECT: string = 'OBJECT_EJECT'; + public static OBJECT_SAVE_STUFF_DATA: string = 'OBJECT_SAVE_STUFF_DATA'; +} \ No newline at end of file diff --git a/src/nitro/room/object/RoomObjectType.ts b/src/nitro/room/object/RoomObjectType.ts new file mode 100644 index 00000000..391cd992 --- /dev/null +++ b/src/nitro/room/object/RoomObjectType.ts @@ -0,0 +1,7 @@ +export class RoomObjectType +{ + public static USER: number = 1; + public static PET: number = 2; + public static BOT: number = 3; + public static RENTABLE_BOT: number = 4; +} \ No newline at end of file diff --git a/src/nitro/room/object/RoomObjectUserType.ts b/src/nitro/room/object/RoomObjectUserType.ts new file mode 100644 index 00000000..9b5906ce --- /dev/null +++ b/src/nitro/room/object/RoomObjectUserType.ts @@ -0,0 +1,40 @@ +export class RoomObjectUserType +{ + public static USER: string = 'user'; + public static PET: string = 'pet'; + public static BOT: string = 'bot'; + public static RENTABLE_BOT: string = 'rentable_bot'; + public static MONSTER_PLANT: string = 'monsterplant'; + public static AVATAR_TYPES: { [key: string]: number } = { 'user': 1, 'pet': 2, 'bot': 3, 'rentable_bot': 4 }; + + public static getTypeNumber(type: string): number + { + return RoomObjectUserType.AVATAR_TYPES[type]; + } + + public static getTypeString(type: number): string + { + for(const key in RoomObjectUserType.AVATAR_TYPES) + { + if(!key) continue; + + if(RoomObjectUserType.AVATAR_TYPES[key] !== type) continue; + + return key; + } + + return null; + } + + public static getRealType(type: string): string + { + switch(type) + { + case RoomObjectUserType.BOT: + case RoomObjectUserType.RENTABLE_BOT: + return RoomObjectUserType.USER; + default: + return type; + } + } +} \ No newline at end of file diff --git a/src/nitro/room/object/RoomObjectVariable.ts b/src/nitro/room/object/RoomObjectVariable.ts new file mode 100644 index 00000000..074f2464 --- /dev/null +++ b/src/nitro/room/object/RoomObjectVariable.ts @@ -0,0 +1,138 @@ +export class RoomObjectVariable +{ + public static OBJECT_ROOM_ID: string = 'object_room_id'; + public static OBJECT_ACCURATE_Z_VALUE: string = 'object_accurate_z_value'; + public static TILE_CURSOR_HEIGHT: string = 'tile_cursor_height'; + public static FIGURE: string = 'figure'; + public static GENDER: string = 'gender'; + public static OWN_USER: string = 'own_user'; + public static FIGURE_CAN_STAND_UP: string = 'figure_can_stand_up'; + public static FIGURE_VERTICAL_OFFSET: string = 'figure_vertical_offset'; + public static FIGURE_TALK: string = 'figure_talk'; + public static FIGURE_DANCE: string = 'figure_dance'; + public static FIGURE_SLEEP: string = 'figure_sleep'; + public static FIGURE_BLINK: string = 'figure_blink'; + public static FIGURE_EFFECT: string = 'figure_effect'; + public static FIGURE_CARRY_OBJECT: string = 'figure_carry_object'; + public static FIGURE_USE_OBJECT: string = 'figure_use_object'; + public static FIGURE_GESTURE: string = 'figure_gesture'; + public static FIGURE_POSTURE: string = 'figure_posture'; + public static FIGURE_POSTURE_PARAMETER: string = 'figure_posture_parameter'; + public static FIGURE_HIGHLIGHT_ENABLE: string = 'figure_highlight_enable'; + public static FIGURE_HIGHLIGHT: string = 'figure_highlight'; + public static FURNITURE_PURCHASER_NAME: string = 'furniture_purchaser_name'; + public static FURNITURE_PURCHASER_FIGURE: string = 'furniture_purchaser_figure'; + public static STD: string = 'std'; + public static FIGURE_SIGN: string = 'figure_sign'; + public static FIGURE_FLAT_CONTROL: string = 'figure_flat_control'; + public static FIGURE_IS_TYPING: string = 'figure_is_typing'; + public static FIGURE_IS_MUTED: string = 'figure_is_muted'; + public static FIGURE_GAINED_EXPERIENCE: string = 'figure_gained_experience'; + public static FIGURE_NUMBER_VALUE: string = 'figure_number_value'; + public static FIGURE_IS_PLAYING_GAME: string = 'figure_is_playing_game'; + public static FIGURE_GUIDE_STATUS: string = 'figure_guide_status'; + public static FIGURE_EXPRESSION: string = 'figure_expression'; + public static HEAD_DIRECTION: string = 'head_direction'; + public static FURNITURE_AUTOMATIC_STATE_INDEX: string = 'furniture_automatic_state_index'; + public static FURNITURE_ALWAYS_STACKABLE: string = 'furniture_always_stackable'; + public static FURNITURE_DISABLE_PICKING_ANIMATION: string = 'furniture_disable_picking_animation'; + public static FURNITURE_DATA_FORMAT: string = 'furniture_data_format'; + public static FURNITURE_UNIQUE_SERIAL_NUMBER: string = 'furniture_unique_serial_number'; + public static FURNITURE_UNIQUE_EDITION_SIZE: string = 'furniture_unique_edition_size'; + public static FURNITURE_CRACKABLE_STATE: string = 'furniture_crackable_state'; + public static FURNITURE_CRACKABLE_HITS: string = 'furniture_crackable_hits'; + public static FURNITURE_CRACKABLE_TARGET: string = 'furniture_crackable_target'; + public static FURNITURE_CREDIT_VALUE: string = 'furniture_credit_value'; + public static FURNITURE_DATA: string = 'furniture_data'; + public static FURNITURE_ITEMDATA: string = 'furniture_itemdata'; + public static FURNITURE_COLOR: string = 'furniture_color'; + public static FURNITURE_LIFT_AMOUNT: string = 'furniure_lift_amount'; + public static FURNITURE_GUILD_CUSTOMIZED_GUILD_ID: string = 'furniture_guild_customized_guild_id'; + public static FURNITURE_GUILD_CUSTOMIZED_BADGE: string = 'furniture_guild_customized_badge'; + public static FURNITURE_GUILD_CUSTOMIZED_COLOR_1: string = 'furniture_guild_customized_color_1'; + public static FURNITURE_GUILD_CUSTOMIZED_COLOR_2: string = 'furniture_guild_customized_color_2'; + public static FURNITURE_STATE_UPDATE_TIME: string = 'furniture_state_update_time'; + public static FURNITURE_SELECTION_DISABLED: string = 'furniture_selection_disabled'; + public static FURNITURE_SIZE_X: string = 'furniture_size_x'; + public static FURNITURE_SIZE_Y: string = 'furniture_size_y'; + public static FURNITURE_SIZE_Z: string = 'furniture_size_z'; + public static FURNITURE_CENTER_X: string = 'furniture_center_x'; + public static FURNITURE_CENTER_Y: string = 'furniture_center_y'; + public static FURNITURE_CENTER_Z: string = 'furniture_center_z'; + public static FURNITURE_ALLOWED_DIRECTIONS: string = 'furniture_allowed_directions'; + public static FURNITURE_AD_URL: string = 'furniture_ad_url'; + public static FURNITURE_TYPE_ID: string = 'furniture_type_id'; + public static FURNITURE_EXTRAS: string = 'furniture_extras'; + public static FURNITURE_EXPIRY_TIME: string = 'furniture_expiry_time'; + public static FURNITURE_EXPIRTY_TIMESTAMP: string = 'furniture_expiry_timestamp'; + public static FURNITURE_REAL_ROOM_OBJECT: string = 'furniture_real_room_object'; + public static FURNITURE_IS_STICKIE: string = 'furniture_is_stickie'; + public static FURNITURE_BRANDING_IMAGE_STATUS: string = 'furniture_branding_image_status'; + public static FURNITURE_BRANDING_IMAGE_URL: string = 'furniture_branding_image_url'; + public static FURNITURE_BRANDING_URL: string = 'furniture_branding_url'; + public static FURNITURE_BRANDING_OFFSET_X: string = 'furniture_branding_offset_x'; + public static FURNITURE_BRANDING_OFFSET_Y: string = 'furniture_branding_offset_y'; + public static FURNITURE_BRANDING_OFFSET_Z: string = 'furniture_branding_offset_z'; + public static FURNITURE_BADGE_IMAGE_STATUS: string = 'furniture_badge_image_status'; + public static FURNITURE_BADGE_ASSET_NAME: string = 'furniture_badge_asset_name'; + public static FURNITURE_BADGE_VISIBLE_IN_STATE: string = 'furniture_badge_visible_in_state'; + public static FURNITURE_ALPHA_MULTIPLIER: string = 'furniture_alpha_multiplier'; + public static FURNITURE_USAGE_POLICY: string = 'furniture_usage_policy'; + public static FURNITURE_OWNER_ID: string = 'furniture_owner_id'; + public static FURNITURE_OWNER_NAME: string = 'furniture_owner_name'; + public static FURNITURE_ROOM_BACKGROUND_COLOR_HUE: string = 'furniture_room_background_color_hue'; + public static FURNITURE_ROOM_BACKGROUND_COLOR_SATURATION: string = 'furniture_room_background_color_saturation'; + public static FURNITURE_ROOM_BACKGROUND_COLOR_LIGHTNESS: string = 'furniture_room_background_color_lightness'; + public static FURNITURE_USES_PLANE_MASK: string = 'furniture_uses_plane_mask'; + public static FURNITURE_PLANE_MASK_TYPE: string = 'furniture_plane_mask_type'; + public static FURNITURE_IS_VARIABLE_HEIGHT: string = 'furniture_is_variable_height'; + public static FURNITURE_VOTE_MAJORITY_RESULT: string = 'furniture_vote_majority_result'; + public static FURNITURE_VOTE_COUNTER_COUNT: string = 'furniture_vote_counter_count'; + public static FURNITURE_SOUNDBLOCK_RELATIVE_ANIMATION_SPEED: string = 'furniture_soundblock_relative_animation_speed'; + public static FURNITURE_MANNEQUIN_NAME: string = 'furniture_mannequin_name'; + public static FURNITURE_MANNEQUIN_GENDER: string = 'furniture_mannequin_gender'; + public static FURNITURE_MANNEQUIN_FIGURE: string = 'furniture_mannequin_figure'; + public static FURNITURE_HIGHSCORE_SCORE_TYPE: string = 'furniture_highscore_score_type'; + public static FURNITURE_HIGHSCORE_CLEAR_TYPE: string = 'furniture_highscore_clear_type'; + public static FURNITURE_HIGHSCORE_DATA_ENTRY_COUNT: string = 'furniture_highscore_data_entry_count'; + public static FURNITURE_HIGHSCORE_DATA_ENTRY_BASE_USERS_: string = 'furniture_highscore_data_entry_base_users_'; + public static FURNITURE_HIGHSCORE_DATA_ENTRY_BASE_SCORE_: string = 'furniture_highscore_data_entry_base_score_'; + public static FURNITURE_INTERNAL_LINK: string = 'furniture_internal_link'; + public static PET_PALETTE_INDEX: string = 'pet_palette_index'; + public static PET_COLOR: string = 'pet_color'; + public static PET_HEAD_ONLY: string = 'pet_head_only'; + public static PET_CUSTOM_LAYER_IDS: string = 'pet_custom_layer_ids'; + public static PET_CUSTOM_PARTS_IDS: string = 'pet_custom_part_ids'; + public static PET_CUSTOM_PALETTE_IDS: string = 'pet_custom_palette_ids'; + public static PET_IS_RIDING: string = 'pet_is_riding'; + public static PET_TYPE: string = 'pet_type'; + public static PET_ALLOWED_DIRECTIONS: string = 'pet_allowed_directions'; + public static RACE: string = 'race'; + public static ROOM_MAP_DATA: string = 'room_map_data'; + public static ROOM_PLANE_MASK_XML: string = 'room_plane_mask_xml'; + public static ROOM_FLOOR_TYPE: string = 'room_floor_type'; + public static ROOM_WALL_TYPE: string = 'room_wall_type'; + public static ROOM_LANDSCAPE_TYPE: string = 'room_landscape_type'; + public static ROOM_WALL_THICKNESS: string = 'room_wall_thickness'; + public static ROOM_FLOOR_THICKNESS: string = 'room_floor_thickness'; + public static ROOM_FLOOR_HOLE_UPDATE_TIME: string = 'room_floor_hole_update_time'; + public static ROOM_FLOOR_VISIBILITY: string = 'room_floor_visibility'; + public static ROOM_WALL_VISIBILITY: string = 'room_wall_visibility'; + public static ROOM_LANDSCAPE_VISIBILITY: string = 'room_landscape_visibility'; + public static ROOM_DOOR_X: string = 'room_door_x'; + public static ROOM_DOOR_Y: string = 'room_door_y'; + public static ROOM_DOOR_Z: string = 'room_door_z'; + public static ROOM_DOOR_DIR: string = 'room_door_dir'; + public static ROOM_BACKGROUND_COLOR: string = 'room_background_color'; + public static ROOM_COLORIZE_BG_ONLY: string = 'room_colorize_bg_only'; + public static ROOM_RANDOM_SEED: string = 'room_random_seed'; + public static ROOM_WORLD_TYPE: string = 'room_world_type'; + public static ROOM_SELECTED_X: string = 'room_selected_x'; + public static ROOM_SELECTED_Y: string = 'room_selected_y'; + public static ROOM_SELECTED_Z: string = 'room_selected_z'; + public static ROOM_SELECTED_PLANE: string = 'room_selected_plane'; + public static IMAGE_QUERY_SCALE: string = 'image_query_scale'; + public static FURNITURE_FRIENDFURNI_ENGRAVING: string = 'furniture_friendfurni_engraving_type'; + public static SESSION_URL_PREFIX: string = 'session_url_prefix'; + public static SESSION_CURRENT_USER_ID: string = 'session_current_user_id'; +} diff --git a/src/nitro/room/object/RoomObjectVisualizationFactory.ts b/src/nitro/room/object/RoomObjectVisualizationFactory.ts new file mode 100644 index 00000000..8f782e78 --- /dev/null +++ b/src/nitro/room/object/RoomObjectVisualizationFactory.ts @@ -0,0 +1,271 @@ +import { IAssetData } from '../../../core/asset/interfaces'; +import { NitroLogger } from '../../../core/common/logger/NitroLogger'; +import { IRoomObjectGraphicVisualization } from '../../../room/object/visualization/IRoomObjectGraphicVisualization'; +import { IObjectVisualizationData } from '../../../room/object/visualization/IRoomObjectVisualizationData'; +import { IRoomObjectVisualizationFactory } from '../../../room/object/visualization/IRoomObjectVisualizationFactory'; +import { RoomObjectSpriteVisualization } from '../../../room/object/visualization/RoomObjectSpriteVisualization'; +import { Nitro } from '../../Nitro'; +import { RoomObjectVisualizationType } from './RoomObjectVisualizationType'; +import { AvatarVisualization } from './visualization/avatar/AvatarVisualization'; +import { AvatarVisualizationData } from './visualization/avatar/AvatarVisualizationData'; +import { FurnitureAnimatedVisualization } from './visualization/furniture/FurnitureAnimatedVisualization'; +import { FurnitureAnimatedVisualizationData } from './visualization/furniture/FurnitureAnimatedVisualizationData'; +import { FurnitureBadgeDisplayVisualization } from './visualization/furniture/FurnitureBadgeDisplayVisualization'; +import { FurnitureBBVisualization } from './visualization/furniture/FurnitureBBVisualization'; +import { FurnitureBottleVisualization } from './visualization/furniture/FurnitureBottleVisualization'; +import { FurnitureBuilderPlaceholderVisualization } from './visualization/furniture/FurnitureBuilderPlaceholderVisualization'; +import { FurnitureCounterClockVisualization } from './visualization/furniture/FurnitureCounterClockVisualization'; +import { FurnitureCuboidVisualization } from './visualization/furniture/FurnitureCuboidVisualization'; +import { FurnitureExternalImageVisualization } from './visualization/furniture/FurnitureExternalImageVisualization'; +import { FurnitureFireworksVisualization } from './visualization/furniture/FurnitureFireworksVisualization'; +import { FurnitureGiftWrappedFireworksVisualization } from './visualization/furniture/FurnitureGiftWrappedFireworksVisualization'; +import { FurnitureGiftWrappedVisualization } from './visualization/furniture/FurnitureGiftWrappedVisualization'; +import { FurnitureGuildCustomizedVisualization } from './visualization/furniture/FurnitureGuildCustomizedVisualization'; +import { FurnitureGuildIsometricBadgeVisualization } from './visualization/furniture/FurnitureGuildIsometricBadgeVisualization'; +import { FurnitureHabboWheelVisualization } from './visualization/furniture/FurnitureHabboWheelVisualization'; +import { FurnitureMannequinVisualization } from './visualization/furniture/FurnitureMannequinVisualization'; +import { FurnitureMannequinVisualizationData } from './visualization/furniture/FurnitureMannequinVisualizationData'; +import { FurniturePartyBeamerVisualization } from './visualization/furniture/FurniturePartyBeamerVisualization'; +import { FurniturePlanetSystemVisualization } from './visualization/furniture/FurniturePlanetSystemVisualization'; +import { FurniturePosterVisualization } from './visualization/furniture/FurniturePosterVisualization'; +import { FurnitureQueueTileVisualization } from './visualization/furniture/FurnitureQueueTileVisualization'; +import { FurnitureResettingAnimatedVisualization } from './visualization/furniture/FurnitureResettingAnimatedVisualization'; +import { FurnitureRoomBackgroundVisualization } from './visualization/furniture/FurnitureRoomBackgroundVisualization'; +import { FurnitureScoreBoardVisualization } from './visualization/furniture/FurnitureScoreBoardVisualization'; +import { FurnitureSoundBlockVisualization } from './visualization/furniture/FurnitureSoundBlockVisualization'; +import { FurnitureStickieVisualization } from './visualization/furniture/FurnitureStickieVisualization'; +import { FurnitureValRandomizerVisualization } from './visualization/furniture/FurnitureValRandomizerVisualization'; +import { FurnitureVisualization } from './visualization/furniture/FurnitureVisualization'; +import { FurnitureVisualizationData } from './visualization/furniture/FurnitureVisualizationData'; +import { FurnitureVoteCounterVisualization } from './visualization/furniture/FurnitureVoteCounterVisualization'; +import { FurnitureVoteMajorityVisualization } from './visualization/furniture/FurnitureVoteMajorityVisualization'; +import { FurnitureWaterAreaVisualization } from './visualization/furniture/FurnitureWaterAreaVisualization'; +import { FurnitureYoutubeVisualization } from './visualization/furniture/FurnitureYoutubeVisualization'; +import { PetVisualization } from './visualization/pet/PetVisualization'; +import { PetVisualizationData } from './visualization/pet/PetVisualizationData'; +import { RoomVisualization } from './visualization/room/RoomVisualization'; +import { RoomVisualizationData } from './visualization/room/RoomVisualizationData'; +import { TileCursorVisualization } from './visualization/room/TileCursorVisualization'; + +export class RoomObjectVisualizationFactory implements IRoomObjectVisualizationFactory +{ + private static CACHING_ENABLED: boolean = true; + + private _visualizationDatas: Map; + + constructor() + { + this._visualizationDatas = new Map(); + } + + public getVisualization(type: string): IRoomObjectGraphicVisualization + { + const visualization = this.getVisualizationType(type); + + if(!visualization) return null; + + return new visualization(); + } + + public getVisualizationType(type: string): typeof RoomObjectSpriteVisualization + { + if(!type) return null; + + let visualization: typeof RoomObjectSpriteVisualization = null; + + switch(type) + { + case RoomObjectVisualizationType.ROOM: + visualization = RoomVisualization; + break; + case RoomObjectVisualizationType.TILE_CURSOR: + visualization = TileCursorVisualization; + break; + case RoomObjectVisualizationType.USER: + case RoomObjectVisualizationType.BOT: + case RoomObjectVisualizationType.RENTABLE_BOT: + visualization = AvatarVisualization; + break; + case RoomObjectVisualizationType.PET_ANIMATED: + visualization = PetVisualization; + break; + case RoomObjectVisualizationType.FURNITURE_STATIC: + visualization = FurnitureVisualization; + break; + case RoomObjectVisualizationType.FURNITURE_ANIMATED: + visualization = FurnitureAnimatedVisualization; + break; + case RoomObjectVisualizationType.FURNITURE_RESETTING_ANIMATED: + visualization = FurnitureResettingAnimatedVisualization; + break; + case RoomObjectVisualizationType.FURNITURE_BADGE_DISPLAY: + visualization = FurnitureBadgeDisplayVisualization; + break; + case RoomObjectVisualizationType.FURNITURE_BG: + visualization = FurnitureRoomBackgroundVisualization; + break; + case RoomObjectVisualizationType.FURNITURE_BB: + visualization = FurnitureBBVisualization; + break; + case RoomObjectVisualizationType.FURNITURE_BOTTLE: + visualization = FurnitureBottleVisualization; + break; + case RoomObjectVisualizationType.FURNITURE_BUILDER_PLACEHOLDER: + visualization = FurnitureBuilderPlaceholderVisualization; + break; + case RoomObjectVisualizationType.FURNITURE_COUNTER_CLOCK: + visualization = FurnitureCounterClockVisualization; + break; + case RoomObjectVisualizationType.FURNITURE_CUBOID: + visualization = FurnitureCuboidVisualization; + break; + case RoomObjectVisualizationType.FURNITURE_EXTERNAL_IMAGE: + visualization = FurnitureExternalImageVisualization; + break; + case RoomObjectVisualizationType.FURNITURE_FIREWORKS: + visualization = FurnitureFireworksVisualization; + break; + case RoomObjectVisualizationType.FURNITURE_GIFT_WRAPPED_FIREWORKS: + visualization = FurnitureGiftWrappedFireworksVisualization; + break; + case RoomObjectVisualizationType.FURNITURE_GIFT_WRAPPED: + visualization = FurnitureGiftWrappedVisualization; + break; + case RoomObjectVisualizationType.FURNITURE_GUILD_CUSTOMIZED: + visualization = FurnitureGuildCustomizedVisualization; + break; + case RoomObjectVisualizationType.FURNITURE_GUILD_ISOMETRIC_BADGE: + visualization = FurnitureGuildIsometricBadgeVisualization; + break; + case RoomObjectVisualizationType.FURNITURE_HABBOWHEEL: + visualization = FurnitureHabboWheelVisualization; + break; + case RoomObjectVisualizationType.FURNITURE_MANNEQUIN: + visualization = FurnitureMannequinVisualization; + break; + case RoomObjectVisualizationType.FURNITURE_PARTY_BEAMER: + visualization = FurniturePartyBeamerVisualization; + break; + case RoomObjectVisualizationType.FURNITURE_PLANET_SYSTEM: + visualization = FurniturePlanetSystemVisualization; + break; + case RoomObjectVisualizationType.FURNITURE_POSTER: + visualization = FurniturePosterVisualization; + break; + case RoomObjectVisualizationType.FURNITURE_QUEUE_TILE: + visualization = FurnitureQueueTileVisualization; + break; + case RoomObjectVisualizationType.FURNITURE_SCORE_BOARD: + visualization = FurnitureScoreBoardVisualization; + break; + case RoomObjectVisualizationType.FURNITURE_SOUNDBLOCK: + visualization = FurnitureSoundBlockVisualization; + break; + case RoomObjectVisualizationType.FURNITURE_STICKIE: + visualization = FurnitureStickieVisualization; + break; + case RoomObjectVisualizationType.FURNITURE_VAL_RANDOMIZER: + visualization = FurnitureValRandomizerVisualization; + break; + case RoomObjectVisualizationType.FURNITURE_VOTE_COUNTER: + visualization = FurnitureVoteCounterVisualization; + break; + case RoomObjectVisualizationType.FURNITURE_VOTE_MAJORITY: + visualization = FurnitureVoteMajorityVisualization; + break; + case RoomObjectVisualizationType.FURNITURE_WATER_AREA: + visualization = FurnitureWaterAreaVisualization; + break; + case RoomObjectVisualizationType.FURNITURE_YOUTUBE: + visualization = FurnitureYoutubeVisualization; + break; + } + + if(!visualization) + { + NitroLogger.log(`Unknown Visualization: ${ type }`); + + return null; + } + + return visualization; + } + + public getVisualizationData(type: string, visualization: string, asset: IAssetData): IObjectVisualizationData + { + const existing = this._visualizationDatas.get(type); + + if(existing) return existing; + + let visualizationData: IObjectVisualizationData = null; + + switch(visualization) + { + case RoomObjectVisualizationType.FURNITURE_STATIC: + case RoomObjectVisualizationType.FURNITURE_GIFT_WRAPPED: + case RoomObjectVisualizationType.FURNITURE_BB: + case RoomObjectVisualizationType.FURNITURE_BG: + case RoomObjectVisualizationType.FURNITURE_STICKIE: + case RoomObjectVisualizationType.FURNITURE_BUILDER_PLACEHOLDER: + visualizationData = new FurnitureVisualizationData(); + break; + case RoomObjectVisualizationType.FURNITURE_ANIMATED: + case RoomObjectVisualizationType.FURNITURE_RESETTING_ANIMATED: + case RoomObjectVisualizationType.FURNITURE_POSTER: + case RoomObjectVisualizationType.FURNITURE_HABBOWHEEL: + case RoomObjectVisualizationType.FURNITURE_VAL_RANDOMIZER: + case RoomObjectVisualizationType.FURNITURE_BOTTLE: + case RoomObjectVisualizationType.FURNITURE_PLANET_SYSTEM: + case RoomObjectVisualizationType.FURNITURE_QUEUE_TILE: + case RoomObjectVisualizationType.FURNITURE_PARTY_BEAMER: + case RoomObjectVisualizationType.FURNITURE_COUNTER_CLOCK: + case RoomObjectVisualizationType.FURNITURE_WATER_AREA: + case RoomObjectVisualizationType.FURNITURE_SCORE_BOARD: + case RoomObjectVisualizationType.FURNITURE_FIREWORKS: + case RoomObjectVisualizationType.FURNITURE_GIFT_WRAPPED_FIREWORKS: + case RoomObjectVisualizationType.FURNITURE_GUILD_CUSTOMIZED: + case RoomObjectVisualizationType.FURNITURE_GUILD_ISOMETRIC_BADGE: + case RoomObjectVisualizationType.FURNITURE_VOTE_COUNTER: + case RoomObjectVisualizationType.FURNITURE_VOTE_MAJORITY: + case RoomObjectVisualizationType.FURNITURE_SOUNDBLOCK: + case RoomObjectVisualizationType.FURNITURE_BADGE_DISPLAY: + case RoomObjectVisualizationType.FURNITURE_EXTERNAL_IMAGE: + case RoomObjectVisualizationType.FURNITURE_YOUTUBE: + case RoomObjectVisualizationType.TILE_CURSOR: + visualizationData = new FurnitureAnimatedVisualizationData(); + break; + case RoomObjectVisualizationType.FURNITURE_MANNEQUIN: + visualizationData = new FurnitureMannequinVisualizationData(); + break; + case RoomObjectVisualizationType.ROOM: + visualizationData = new RoomVisualizationData(); + break; + case RoomObjectVisualizationType.USER: + case RoomObjectVisualizationType.BOT: + case RoomObjectVisualizationType.RENTABLE_BOT: + visualizationData = new AvatarVisualizationData(); + break; + case RoomObjectVisualizationType.PET_ANIMATED: + visualizationData = new PetVisualizationData(); + break; + } + + if(!visualizationData) return null; + + if(!visualizationData.initialize(asset)) + { + visualizationData.dispose(); + + return null; + } + + if((visualizationData instanceof AvatarVisualizationData) || (visualizationData instanceof FurnitureMannequinVisualizationData)) + { + visualizationData.avatarManager = Nitro.instance.avatar; + } + + if(RoomObjectVisualizationFactory.CACHING_ENABLED) this._visualizationDatas.set(type, visualizationData); + + return visualizationData; + } +} diff --git a/src/nitro/room/object/RoomObjectVisualizationType.ts b/src/nitro/room/object/RoomObjectVisualizationType.ts new file mode 100644 index 00000000..48572465 --- /dev/null +++ b/src/nitro/room/object/RoomObjectVisualizationType.ts @@ -0,0 +1,39 @@ +export class RoomObjectVisualizationType +{ + public static FURNITURE_STATIC = 'furniture_static'; + public static FURNITURE_ANIMATED = 'furniture_animated'; + public static FURNITURE_RESETTING_ANIMATED = 'furniture_resetting_animated'; + public static FURNITURE_POSTER = 'furniture_poster'; + public static FURNITURE_EXTERNAL_IMAGE = 'furniture_external_image'; + public static FURNITURE_HABBOWHEEL = 'furniture_habbowheel'; + public static FURNITURE_VAL_RANDOMIZER = 'furniture_val_randomizer'; + public static FURNITURE_BOTTLE = 'furniture_bottle'; + public static FURNITURE_PLANET_SYSTEM = 'furniture_planet_system'; + public static FURNITURE_QUEUE_TILE = 'furniture_queue_tile'; + public static FURNITURE_PARTY_BEAMER = 'furniture_party_beamer'; + public static FURNITURE_CUBOID = 'furniture_cuboid'; + public static FURNITURE_GIFT_WRAPPED = 'furniture_gift_wrapped'; + public static FURNITURE_GIFT_WRAPPED_FIREWORKS = 'furniture_gift_wrapped_fireworks'; + public static FURNITURE_COUNTER_CLOCK = 'furniture_counter_clock'; + public static FURNITURE_WATER_AREA = 'furniture_water_area'; + public static FURNITURE_SCORE_BOARD = 'furniture_score_board'; + public static FURNITURE_FIREWORKS = 'furniture_fireworks'; + public static FURNITURE_BB = 'furniture_bb'; + public static FURNITURE_BG = 'furniture_bg'; + public static FURNITURE_STICKIE = 'furniture_stickie'; + public static FURNITURE_MANNEQUIN = 'furniture_mannequin'; + public static FURNITURE_GUILD_CUSTOMIZED = 'furniture_guild_customized'; + public static FURNITURE_GUILD_ISOMETRIC_BADGE = 'furniture_guild_isometric_badge'; + public static FURNITURE_VOTE_COUNTER = 'furniture_vote_counter'; + public static FURNITURE_VOTE_MAJORITY = 'furniture_vote_majority'; + public static FURNITURE_SOUNDBLOCK = 'furniture_soundblock'; + public static FURNITURE_BADGE_DISPLAY = 'furniture_badge_display'; + public static FURNITURE_YOUTUBE = 'furniture_youtube'; + public static FURNITURE_BUILDER_PLACEHOLDER = 'furniture_builder_placeholder'; + public static ROOM = 'room'; + public static USER = 'user'; + public static PET_ANIMATED = 'pet_animated'; + public static BOT = 'bot'; + public static RENTABLE_BOT = 'rentable_bot'; + public static TILE_CURSOR = 'tile_cursor'; +} \ No newline at end of file diff --git a/src/nitro/room/object/RoomPlaneBitmapMaskData.ts b/src/nitro/room/object/RoomPlaneBitmapMaskData.ts new file mode 100644 index 00000000..ae106952 --- /dev/null +++ b/src/nitro/room/object/RoomPlaneBitmapMaskData.ts @@ -0,0 +1,56 @@ +import { IVector3D } from '../../../room/utils/IVector3D'; +import { Vector3d } from '../../../room/utils/Vector3d'; + +export class RoomPlaneBitmapMaskData +{ + public static WINDOW: string = 'window'; + public static HOLE:string = 'hole'; + + private _loc: Vector3d; + private _type: string; + private _category: string; + + constructor(type: string, loc: IVector3D, category: string) + { + this.type = type; + this.loc = loc; + this.category = category; + } + + public get loc(): IVector3D + { + return this._loc; + } + + public set loc(k:IVector3D) + { + if(!this._loc) this._loc = new Vector3d(); + + this._loc.assign(k); + } + + public get type(): string + { + return this._type; + } + + public set type(type: string) + { + this._type = type; + } + + public get category(): string + { + return this._category; + } + + public set category(category: string) + { + this._category = category; + } + + public dispose(): void + { + this._loc = null; + } +} \ No newline at end of file diff --git a/src/nitro/room/object/RoomPlaneBitmapMaskParser.ts b/src/nitro/room/object/RoomPlaneBitmapMaskParser.ts new file mode 100644 index 00000000..70f2b93e --- /dev/null +++ b/src/nitro/room/object/RoomPlaneBitmapMaskParser.ts @@ -0,0 +1,147 @@ +import { IVector3D } from '../../../room/utils/IVector3D'; +import { RoomMapMaskData } from './RoomMapMaskData'; +import { RoomPlaneBitmapMaskData } from './RoomPlaneBitmapMaskData'; + +export class RoomPlaneBitmapMaskParser +{ + private _masks: Map; + + constructor() + { + this._masks = new Map(); + } + + public get _Str_6845(): number + { + return this._masks.size; + } + + public dispose(): void + { + if(this._masks) + { + this.reset(); + + this._masks = null; + } + } + + public initialize(k: RoomMapMaskData): boolean + { + if(!k) return false; + + this._masks.clear(); + + if(k.masks.length) + { + for(const mask of k.masks) + { + if(!mask) continue; + + const location = mask.locations.length ? mask.locations[0] : null; + + if(!location) continue; + + this._masks.set(mask.id, new RoomPlaneBitmapMaskData(mask.type, location, mask.category)); + } + } + + return true; + } + + public reset(): void + { + for(const mask of this._masks.values()) + { + if(!mask) continue; + + mask.dispose(); + } + + this._masks.clear(); + } + + public addMask(k: string, _arg_2: string, _arg_3: IVector3D, _arg_4: string): void + { + const mask = new RoomPlaneBitmapMaskData(_arg_2, _arg_3, _arg_4); + + this._masks.delete(k); + this._masks.set(k, mask); + } + + public _Str_23574(k: string): boolean + { + const existing = this._masks.get(k); + + if(existing) + { + this._masks.delete(k); + + existing.dispose(); + + return true; + } + + return false; + } + + public _Str_5598(): RoomMapMaskData + { + const data = new RoomMapMaskData(); + + for(const [ key, mask ] of this._masks.entries()) + { + if(!mask) continue; + + const type = this._Str_21678(mask); + const category = this._Str_21644(mask); + const location = this._Str_19038(mask); + + if(type && category && location) + { + const newMask: any = { + id: key, + type: type, + category: category, + locations: [ + { + x: location.x, + y: location.y, + z: location.z + } + ] + }; + + data.masks.push(newMask); + } + } + + return data; + } + + public _Str_19038(mask: RoomPlaneBitmapMaskData): IVector3D + { + if(!mask) return null; + + return mask.loc; + } + + public _Str_21678(mask: RoomPlaneBitmapMaskData): string + { + if(!mask) return null; + + return mask.type; + } + + public _Str_21644(mask: RoomPlaneBitmapMaskData): string + { + if(!mask) return null; + + return mask.category; + } + + public get masks(): Map + { + return this._masks; + } +} \ No newline at end of file diff --git a/src/nitro/room/object/RoomPlaneData.ts b/src/nitro/room/object/RoomPlaneData.ts new file mode 100644 index 00000000..e9f8f4c7 --- /dev/null +++ b/src/nitro/room/object/RoomPlaneData.ts @@ -0,0 +1,202 @@ +import { IVector3D } from '../../../room/utils/IVector3D'; +import { Vector3d } from '../../../room/utils/Vector3d'; +import { RoomPlaneMaskData } from './RoomPlaneMaskData'; + +export class RoomPlaneData +{ + public static PLANE_UNDEFINED: number = 0; + public static PLANE_FLOOR: number = 1; + public static PLANE_WALL: number = 2; + public static PLANE_LANDSCAPE: number = 3; + public static PLANE_BILLBOARD: number = 4; + + private _type: number = 0; + private _loc: Vector3d = null; + private _leftSide: Vector3d = null; + private _rightSide: Vector3d = null; + private _normal: Vector3d = null; + private _normalDirection: Vector3d = null; + private _secondaryNormals: Vector3d[]; + private _masks: RoomPlaneMaskData[]; + + constructor(k: number, _arg_2: IVector3D, _arg_3: IVector3D, _arg_4: IVector3D, _arg_5: IVector3D[]) + { + let _local_6: number; + let _local_7: number; + let _local_8: number; + let _local_9: number; + let _local_10: number; + let _local_11: number; + let _local_12: IVector3D; + let _local_13: Vector3d; + this._secondaryNormals = []; + this._masks = []; + this._loc = new Vector3d(); + this._loc.assign(_arg_2); + this._leftSide = new Vector3d(); + this._leftSide.assign(_arg_3); + this._rightSide = new Vector3d(); + this._rightSide.assign(_arg_4); + this._type = k; + if(((!(_arg_3 == null)) && (!(_arg_4 == null)))) + { + this._normal = Vector3d.crossProduct(_arg_3, _arg_4); + _local_6 = 0; + _local_7 = 0; + _local_8 = 0; + _local_9 = 0; + _local_10 = 0; + if(((!(this.normal.x == 0)) || (!(this.normal.y == 0)))) + { + _local_9 = this.normal.x; + _local_10 = this.normal.y; + _local_6 = (360 + ((Math.atan2(_local_10, _local_9) / Math.PI) * 180)); + if(_local_6 >= 360) + { + _local_6 = (_local_6 - 360); + } + _local_9 = Math.sqrt(((this.normal.x * this.normal.x) + (this.normal.y * this.normal.y))); + _local_10 = this.normal.z; + _local_7 = (360 + ((Math.atan2(_local_10, _local_9) / Math.PI) * 180)); + if(_local_7 >= 360) + { + _local_7 = (_local_7 - 360); + } + } + else + { + if(this.normal.z < 0) + { + _local_7 = 90; + } + else + { + _local_7 = 270; + } + } + this._normalDirection = new Vector3d(_local_6, _local_7, _local_8); + } + if(((!(_arg_5 == null)) && (_arg_5.length > 0))) + { + _local_11 = 0; + while(_local_11 < _arg_5.length) + { + _local_12 = _arg_5[_local_11]; + if(((!(_local_12 == null)) && (_local_12.length > 0))) + { + _local_13 = new Vector3d(); + _local_13.assign(_local_12); + _local_13.multiply((1 / _local_13.length)); + this._secondaryNormals.push(_local_13); + } + _local_11++; + } + } + } + + public get type(): number + { + return this._type; + } + + public get loc(): IVector3D + { + return this._loc; + } + + public get _Str_5424(): IVector3D + { + return this._leftSide; + } + + public get _Str_4968(): IVector3D + { + return this._rightSide; + } + + public get normal(): IVector3D + { + return this._normal; + } + + public get _Str_25207(): IVector3D + { + return this._normalDirection; + } + + public get _Str_20277(): number + { + return this._secondaryNormals.length; + } + + public get _Str_6845(): number + { + return this._masks.length; + } + + public _Str_22585(k: number): IVector3D + { + if(((k < 0) || (k >= this._Str_20277))) + { + return null; + } + const _local_2:Vector3d = new Vector3d(); + _local_2.assign((this._secondaryNormals[k] as IVector3D)); + return _local_2; + } + + public addMask(k: number, _arg_2: number, _arg_3: number, _arg_4: number): void + { + const _local_5:RoomPlaneMaskData = new RoomPlaneMaskData(k, _arg_2, _arg_3, _arg_4); + this._masks.push(_local_5); + } + + private _Str_8361(k: number):RoomPlaneMaskData + { + if(((k < 0) || (k >= this._Str_6845))) + { + return null; + } + return this._masks[k]; + } + + public _Str_25133(k: number): number + { + const _local_2:RoomPlaneMaskData = this._Str_8361(k); + if(_local_2 != null) + { + return _local_2._Str_5120; + } + return -1; + } + + public _Str_23609(k: number): number + { + const _local_2:RoomPlaneMaskData = this._Str_8361(k); + if(_local_2 != null) + { + return _local_2._Str_4659; + } + return -1; + } + + public _Str_25097(k: number): number + { + const _local_2:RoomPlaneMaskData = this._Str_8361(k); + if(_local_2 != null) + { + return _local_2._Str_9124; + } + return -1; + } + + public _Str_25617(k: number): number + { + const _local_2:RoomPlaneMaskData = this._Str_8361(k); + if(_local_2 != null) + { + return _local_2._Str_12156; + } + return -1; + } +} \ No newline at end of file diff --git a/src/nitro/room/object/RoomPlaneMaskData.ts b/src/nitro/room/object/RoomPlaneMaskData.ts new file mode 100644 index 00000000..328fccac --- /dev/null +++ b/src/nitro/room/object/RoomPlaneMaskData.ts @@ -0,0 +1,35 @@ +export class RoomPlaneMaskData +{ + private _leftSideLoc: number = 0; + private _rightSideLoc: number = 0; + private _leftSideLength: number = 0; + private _rightSideLength: number = 0; + + constructor(k: number, _arg_2: number, _arg_3: number, _arg_4: number) + { + this._leftSideLoc = k; + this._rightSideLoc = _arg_2; + this._leftSideLength = _arg_3; + this._rightSideLength = _arg_4; + } + + public get _Str_5120(): number + { + return this._leftSideLoc; + } + + public get _Str_4659(): number + { + return this._rightSideLoc; + } + + public get _Str_9124(): number + { + return this._leftSideLength; + } + + public get _Str_12156(): number + { + return this._rightSideLength; + } +} \ No newline at end of file diff --git a/src/nitro/room/object/RoomPlaneParser.ts b/src/nitro/room/object/RoomPlaneParser.ts new file mode 100644 index 00000000..827a8a16 --- /dev/null +++ b/src/nitro/room/object/RoomPlaneParser.ts @@ -0,0 +1,1700 @@ +import { Point } from 'pixi.js'; +import { IVector3D } from '../../../room/utils/IVector3D'; +import { Vector3d } from '../../../room/utils/Vector3d'; +import { RoomFloorHole } from './RoomFloorHole'; +import { RoomMapData } from './RoomMapData'; +import { RoomPlaneData } from './RoomPlaneData'; +import { RoomWallData } from './RoomWallData'; + +export class RoomPlaneParser +{ + private static FLOOR_THICKNESS: number = 0.25; + private static WALL_THICKNESS: number = 0.25; + private static MAX_WALL_ADDITIONAL_HEIGHT: number = 20; + + public static TILE_BLOCKED: number = -110; + public static TILE_HOLE: number = -100; + + private _tileMatrix: number[][]; + private _tileMatrixOriginal: number[][]; + private _width: number = 0; + private _height: number = 0; + private _minX: number = 0; + private _maxX: number = 0; + private _minY: number = 0; + private _maxY: number = 0; + private _planes: RoomPlaneData[]; + private _wallHeight: number; + private _wallThicknessMultiplier: number; + private _floorThicknessMultiplier: number; + private _fixedWallHeight: number = -1; + private _floorHeight: number = 0; + private _floorHoles: Map; + private _floorHoleMatrix: boolean[][]; + private _restrictsDragging: boolean; + private _restrictsScaling: boolean = false; + private _restrictedScale: number = 1; + + constructor() + { + this._tileMatrix = []; + this._tileMatrixOriginal = []; + this._planes = []; + this._floorHoleMatrix = []; + this._wallHeight = 3.6; + this._wallThicknessMultiplier = 1; + this._floorThicknessMultiplier = 1; + this._floorHoles = new Map(); + } + + private static getFloorHeight(matricies: number[][]): number + { + const length = matricies.length; + + if(!length) return 0; + + let tileHeight = 0; + + let i = 0; + + while(i < length) + { + const matrix = matricies[i]; + + let j = 0; + + while(j < matrix.length) + { + const height = matrix[j]; + + if(height > tileHeight) tileHeight = height; + + j++; + } + + i++; + } + + return tileHeight; + } + + private static findEntranceTile(matricies: number[][]): Point + { + if(!matricies) return null; + + const length = matricies.length; + + if(!length) return null; + + const _local_6: number[] = []; + + let i = 0; + + while(i < length) + { + const matrix = matricies[i]; + + if(!matrix || !matrix.length) return null; + + let j = 0; + + while(j < matrix.length) + { + if(matrix[j] >= 0) + { + _local_6.push(j); + + break; + } + + j++; + } + + if(_local_6.length < (i + 1)) _local_6.push((matrix.length + 1)); + + i++; + } + + i = 1; + + while(i < (_local_6.length - 1)) + { + if(((Math.trunc(_local_6[i]) <= (Math.trunc(_local_6[(i - 1)]) - 1)) && (Math.trunc(_local_6[i]) <= (Math.trunc(_local_6[(i + 1)]) - 1)))) return new Point(Math.trunc((_local_6[i]) | 0), i); + + i++; + } + + return null; + } + + private static expandFloorTiles(k: number[][]): number[][] + { + let _local_5: number; + let _local_6: number; + let _local_7: number; + let _local_8: number; + let _local_10: number; + let _local_11: number; + let _local_12: number; + let _local_13: number; + let _local_14: number; + let _local_15: number; + let _local_16: number; + let _local_17: number; + const _local_2 = k.length; + const _local_3: number = k[0].length; + const _local_4: number[][] = []; + _local_6 = 0; + while(_local_6 < (_local_2 * 4)) + { + _local_4[_local_6] = []; + _local_6++; + } + let _local_9 = 0; + _local_6 = 0; + while(_local_6 < _local_2) + { + _local_10 = 0; + _local_5 = 0; + while(_local_5 < _local_3) + { + _local_11 = k[_local_6][_local_5]; + if(((_local_11 < 0) || (_local_11 <= 0xFF))) + { + _local_8 = 0; + while(_local_8 < 4) + { + _local_7 = 0; + while(_local_7 < 4) + { + if(_local_4[(_local_9 + _local_8)] === undefined) _local_4[(_local_9 + _local_8)] = []; + + _local_4[(_local_9 + _local_8)][(_local_10 + _local_7)] = ((_local_11 < 0) ? _local_11 : (_local_11 * 4)); + _local_7++; + } + _local_8++; + } + } + else + { + _local_12 = ((_local_11 & 0xFF) * 4); + _local_13 = (_local_12 + (((_local_11 >> 11) & 0x01) * 3)); + _local_14 = (_local_12 + (((_local_11 >> 10) & 0x01) * 3)); + _local_15 = (_local_12 + (((_local_11 >> 9) & 0x01) * 3)); + _local_16 = (_local_12 + (((_local_11 >> 8) & 0x01) * 3)); + _local_7 = 0; + while(_local_7 < 3) + { + _local_17 = (_local_7 + 1); + _local_4[_local_9][(_local_10 + _local_7)] = (((_local_13 * (3 - _local_7)) + (_local_14 * _local_7)) / 3); + _local_4[(_local_9 + 3)][(_local_10 + _local_17)] = (((_local_15 * (3 - _local_17)) + (_local_16 * _local_17)) / 3); + _local_4[(_local_9 + _local_17)][_local_10] = (((_local_13 * (3 - _local_17)) + (_local_15 * _local_17)) / 3); + _local_4[(_local_9 + _local_7)][(_local_10 + 3)] = (((_local_14 * (3 - _local_7)) + (_local_16 * _local_7)) / 3); + _local_7++; + } + _local_4[(_local_9 + 1)][(_local_10 + 1)] = ((_local_13 > _local_12) ? (_local_12 + 2) : (_local_12 + 1)); + _local_4[(_local_9 + 1)][(_local_10 + 2)] = ((_local_14 > _local_12) ? (_local_12 + 2) : (_local_12 + 1)); + _local_4[(_local_9 + 2)][(_local_10 + 1)] = ((_local_15 > _local_12) ? (_local_12 + 2) : (_local_12 + 1)); + _local_4[(_local_9 + 2)][(_local_10 + 2)] = ((_local_16 > _local_12) ? (_local_12 + 2) : (_local_12 + 1)); + } + _local_10 = (_local_10 + 4); + _local_5++; + } + _local_9 = (_local_9 + 4); + _local_6++; + } + return _local_4; + } + + private static addTileTypes(k: number[][]): void + { + let _local_4: number; + let _local_5: number; + let _local_6: number; + let _local_7: number; + let _local_8: number; + let _local_9: number; + let _local_10: number; + let _local_11: number; + let _local_12: number; + let _local_13: number; + let _local_14: number; + let _local_15: number; + let _local_16: number; + let _local_17: number; + const _local_2: number = (k.length - 1); + const _local_3: number = (k[0].length - 1); + _local_5 = 1; + while(_local_5 < _local_2) + { + _local_4 = 1; + while(_local_4 < _local_3) + { + _local_6 = k[_local_5][_local_4]; + if(_local_6 < 0) + { + // + } + else + { + _local_7 = (k[(_local_5 - 1)][(_local_4 - 1)] & 0xFF); + _local_8 = (k[(_local_5 - 1)][_local_4] & 0xFF); + _local_9 = (k[(_local_5 - 1)][(_local_4 + 1)] & 0xFF); + _local_10 = (k[_local_5][(_local_4 - 1)] & 0xFF); + _local_11 = (k[_local_5][(_local_4 + 1)] & 0xFF); + _local_12 = (k[(_local_5 + 1)][(_local_4 - 1)] & 0xFF); + _local_13 = (k[(_local_5 + 1)][_local_4] & 0xFF); + _local_14 = (k[(_local_5 + 1)][(_local_4 + 1)] & 0xFF); + _local_15 = (_local_6 + 1); + _local_16 = (_local_6 - 1); + _local_17 = (((((((_local_7 == _local_15) || (_local_8 == _local_15)) || (_local_10 == _local_15)) ? 8 : 0) | ((((_local_9 == _local_15) || (_local_8 == _local_15)) || (_local_11 == _local_15)) ? 4 : 0)) | ((((_local_12 == _local_15) || (_local_13 == _local_15)) || (_local_10 == _local_15)) ? 2 : 0)) | ((((_local_14 == _local_15) || (_local_13 == _local_15)) || (_local_11 == _local_15)) ? 1 : 0)); + if(_local_17 == 15) + { + _local_17 = 0; + } + k[_local_5][_local_4] = (_local_6 | (_local_17 << 8)); + } + _local_4++; + } + _local_5++; + } + } + + private static unpadHeightMap(k: number[][]): void + { + k.shift(); + k.pop(); + + for(const _local_2 of k) + { + _local_2.shift(); + _local_2.pop(); + } + } + + private static padHeightMap(k: number[][]): void + { + const _local_2: number[] = []; + const _local_3: number[] = []; + for(const _local_4 of k) + { + _local_4.push(RoomPlaneParser.TILE_BLOCKED); + _local_4.unshift(RoomPlaneParser.TILE_BLOCKED); + } + for(const _local_5 of k[0]) + { + _local_2.push(RoomPlaneParser.TILE_BLOCKED); + _local_3.push(RoomPlaneParser.TILE_BLOCKED); + } + k.push(_local_3); + k.unshift(_local_2); + } + + + public get minX(): number + { + return this._minX; + } + + public get maxX(): number + { + return this._maxX; + } + + public get minY(): number + { + return this._minY; + } + + public get maxY(): number + { + return this._maxY; + } + + public get tileMapWidth(): number + { + return this._width; + } + + public get tileMapHeight(): number + { + return this._height; + } + + public get planeCount(): number + { + return this._planes.length; + } + + public get floorHeight(): number + { + if(this._fixedWallHeight != -1) + { + return this._fixedWallHeight; + } + return this._floorHeight; + } + + public get wallHeight(): number + { + if(this._fixedWallHeight != -1) + { + return this._fixedWallHeight + 3.6; + } + return this._wallHeight; + } + + public set wallHeight(k: number) + { + if(k < 0) + { + k = 0; + } + this._wallHeight = k; + } + + public get wallThicknessMultiplier(): number + { + return this._wallThicknessMultiplier; + } + + public set wallThicknessMultiplier(k: number) + { + if(k < 0) + { + k = 0; + } + this._wallThicknessMultiplier = k; + } + + public get floorThicknessMultiplier(): number + { + return this._floorThicknessMultiplier; + } + + public set floorThicknessMultiplier(k: number) + { + if(k < 0) + { + k = 0; + } + this._floorThicknessMultiplier = k; + } + + public dispose(): void + { + this._planes = null; + this._tileMatrix = null; + this._tileMatrixOriginal = null; + this._floorHoleMatrix = null; + if(this._floorHoles != null) + { + this._floorHoles.clear(); + this._floorHoles = null; + } + } + + public reset(): void + { + this._planes = []; + this._tileMatrix = []; + this._tileMatrixOriginal = []; + this._width = 0; + this._height = 0; + this._minX = 0; + this._maxX = 0; + this._minY = 0; + this._maxY = 0; + this._floorHeight = 0; + this._floorHoleMatrix = []; + } + + public initializeTileMap(width: number, height: number): boolean + { + if(width < 0) width = 0; + + if(height < 0) height = 0; + + this._tileMatrix = []; + this._tileMatrixOriginal = []; + this._floorHoleMatrix = []; + + let y = 0; + + while(y < height) + { + const tileMatrix = []; + const tileMatrixOriginal = []; + const floorHoleMatrix = []; + + let x = 0; + + while(x < width) + { + tileMatrix[x] = RoomPlaneParser.TILE_BLOCKED; + tileMatrixOriginal[x] = RoomPlaneParser.TILE_BLOCKED; + floorHoleMatrix[x] = false; + + x++; + } + + this._tileMatrix.push(tileMatrix); + this._tileMatrixOriginal.push(tileMatrixOriginal); + this._floorHoleMatrix.push(floorHoleMatrix); + + y++; + } + + this._width = width; + this._height = height; + this._minX = this._width; + this._maxX = -1; + this._minY = this._height; + this._maxY = -1; + + return true; + } + + public setTileHeight(k: number, _arg_2: number, _arg_3: number): boolean + { + let _local_4: number[]; + let _local_5: boolean; + let _local_6: number; + let _local_7: boolean; + let _local_8: number; + if(((((k >= 0) && (k < this._width)) && (_arg_2 >= 0)) && (_arg_2 < this._height))) + { + _local_4 = this._tileMatrix[_arg_2]; + + _local_4[k] = _arg_3; + if(_arg_3 >= 0) + { + if(k < this._minX) + { + this._minX = k; + } + if(k > this._maxX) + { + this._maxX = k; + } + if(_arg_2 < this._minY) + { + this._minY = _arg_2; + } + if(_arg_2 > this._maxY) + { + this._maxY = _arg_2; + } + } + else + { + if(((k == this._minX) || (k == this._maxX))) + { + _local_5 = false; + _local_6 = this._minY; + while(_local_6 < this._maxY) + { + if(this.getTileHeightInternal(k, _local_6) >= 0) + { + _local_5 = true; + break; + } + _local_6++; + } + if(!_local_5) + { + if(k == this._minX) + { + this._minX++; + } + if(k == this._maxX) + { + this._maxX--; + } + } + } + if(((_arg_2 == this._minY) || (_arg_2 == this._maxY))) + { + _local_7 = false; + _local_8 = this._minX; + while(_local_8 < this._maxX) + { + if(this.getTileHeight(_local_8, _arg_2) >= 0) + { + _local_7 = true; + break; + } + _local_8++; + } + if(!_local_7) + { + if(_arg_2 == this._minY) + { + this._minY++; + } + if(_arg_2 == this._maxY) + { + this._maxY--; + } + } + } + } + return true; + } + return false; + } + + public getTileHeight(k: number, _arg_2: number): number + { + if(((((k < 0) || (k >= this._width)) || (_arg_2 < 0)) || (_arg_2 >= this._height))) + { + return RoomPlaneParser.TILE_BLOCKED; + } + + const _local_3 = this._tileMatrix[_arg_2]; + + if(_local_3[k] === undefined) return 0; + + return Math.abs(_local_3[k]); + } + + private getTileHeightOriginal(k: number, _arg_2: number): number + { + if(((((k < 0) || (k >= this._width)) || (_arg_2 < 0)) || (_arg_2 >= this._height))) + { + return RoomPlaneParser.TILE_BLOCKED; + } + if(this._floorHoleMatrix[_arg_2][k]) + { + return RoomPlaneParser.TILE_HOLE; + } + const _local_3 = this._tileMatrixOriginal[_arg_2]; + return _local_3[k]; + } + + private getTileHeightInternal(k: number, _arg_2: number): number + { + if(((((k < 0) || (k >= this._width)) || (_arg_2 < 0)) || (_arg_2 >= this._height))) + { + return RoomPlaneParser.TILE_BLOCKED; + } + const _local_3 = this._tileMatrix[_arg_2]; + return _local_3[k]; + } + + public initializeFromTileData(k: number=-1): boolean + { + let _local_2: number; + let _local_3: number; + this._fixedWallHeight = k; + _local_3 = 0; + while(_local_3 < this._height) + { + _local_2 = 0; + while(_local_2 < this._width) + { + if(this._tileMatrixOriginal[_local_3] === undefined) this._tileMatrixOriginal[_local_3] = []; + this._tileMatrixOriginal[_local_3][_local_2] = this._tileMatrix[_local_3][_local_2]; + _local_2++; + } + _local_3++; + } + const _local_4: Point = RoomPlaneParser.findEntranceTile(this._tileMatrix); + + _local_3 = 0; + while(_local_3 < this._height) + { + _local_2 = 0; + while(_local_2 < this._width) + { + if(this._floorHoleMatrix[_local_3] === undefined) this._floorHoleMatrix[_local_3] = []; + if(this._floorHoleMatrix[_local_3][_local_2]) + { + this.setTileHeight(_local_2, _local_3, RoomPlaneParser.TILE_HOLE); + } + _local_2++; + } + _local_3++; + } + + return this.initialize(_local_4); + } + + private initialize(k: Point): boolean + { + let _local_2 = 0; + if(k != null) + { + _local_2 = this.getTileHeight(k.x, k.y); + this.setTileHeight(k.x, k.y, RoomPlaneParser.TILE_BLOCKED); + } + this._floorHeight = RoomPlaneParser.getFloorHeight(this._tileMatrix); + this.createWallPlanes(); + const _local_3: number[][] = []; + + for(const _local_4 of this._tileMatrix) _local_3.push(_local_4.concat()); + + RoomPlaneParser.padHeightMap(_local_3); + RoomPlaneParser.addTileTypes(_local_3); + RoomPlaneParser.unpadHeightMap(_local_3); + const _local_5 = RoomPlaneParser.expandFloorTiles(_local_3); + this.extractPlanes(_local_5); + if(k != null) + { + this.setTileHeight(k.x, k.y, _local_2); + this.addFloor(new Vector3d((k.x + 0.5), (k.y + 0.5), _local_2), new Vector3d(-1, 0, 0), new Vector3d(0, -1, 0), false, false, false, false); + } + + return true; + } + + private generateWallData(k: Point, _arg_2: boolean): RoomWallData + { + let _local_8: boolean; + let _local_9: boolean; + let _local_10: number; + let _local_11: Point; + let _local_12: number; + const _local_3: RoomWallData = new RoomWallData(); + const _local_4: Function[] = [this.extractTopWall.bind(this), this.extractRightWall.bind(this), this.extractBottomWall.bind(this), this.extractLeftWall.bind(this)]; + let _local_5 = 0; + let _local_6: Point = new Point(k.x, k.y); + let _local_7 = 0; + while(_local_7++ < 1000) + { + _local_8 = false; + _local_9 = false; + _local_10 = _local_5; + if(((((_local_6.x < this.minX) || (_local_6.x > this.maxX)) || (_local_6.y < this.minY)) || (_local_6.y > this.maxY))) + { + _local_8 = true; + } + _local_11 = _local_4[_local_5](_local_6, _arg_2); + if(_local_11 == null) + { + return null; + } + _local_12 = (Math.abs((_local_11.x - _local_6.x)) + Math.abs((_local_11.y - _local_6.y))); + if(((_local_6.x == _local_11.x) || (_local_6.y == _local_11.y))) + { + _local_5 = (((_local_5 - 1) + _local_4.length) % _local_4.length); + _local_12 = (_local_12 + 1); + _local_9 = true; + } + else + { + _local_5 = ((_local_5 + 1) % _local_4.length); + _local_12--; + } + _local_3._Str_17862(_local_6, _local_10, _local_12, _local_8, _local_9); + if((((_local_11.x == k.x) && (_local_11.y == k.y)) && ((!(_local_11.x == _local_6.x)) || (!(_local_11.y == _local_6.y))))) + { + break; + } + _local_6 = _local_11; + } + if(_local_3.count == 0) + { + return null; + } + return _local_3; + } + + private hidePeninsulaWallChains(k: RoomWallData): void + { + let _local_5: number; + let _local_6: number; + let _local_7: boolean; + let _local_8: number; + let _local_2 = 0; + const _local_3: number = k.count; + while(_local_2 < _local_3) + { + const _local_4 = _local_2; + + _local_5 = _local_2; + _local_6 = 0; + _local_7 = false; + while(((!(k._Str_25208(_local_2))) && (_local_2 < _local_3))) + { + if(k._Str_17084(_local_2)) + { + _local_6++; + } + else + { + if(_local_6 > 0) + { + _local_6--; + } + } + if(_local_6 > 1) + { + _local_7 = true; + } + _local_5 = _local_2; + _local_2++; + } + if(_local_7) + { + _local_8 = _local_4; + while(_local_8 <= _local_5) + { + k._Str_15901(_local_8, true); + _local_8++; + } + } + _local_2++; + } + } + + private updateWallsNextToHoles(k: RoomWallData): void + { + let _local_4: Point; + let _local_5: number; + let _local_6: number; + let _local_7: IVector3D; + let _local_8: IVector3D; + let _local_9: number; + let _local_10: number; + const _local_2: number = k.count; + let _local_3 = 0; + while(_local_3 < _local_2) + { + if(!k._Str_10019(_local_3)) + { + _local_4 = k._Str_10778(_local_3); + _local_5 = k.getDirection(_local_3); + _local_6 = k._Str_13743(_local_3); + _local_7 = RoomWallData.WALL_DIRECTION_VECTORS[_local_5]; + _local_8 = RoomWallData.WALL_NORMAL_VECTORS[_local_5]; + _local_9 = 0; + _local_10 = 0; + while(_local_10 < _local_6) + { + if(this.getTileHeightInternal(((_local_4.x + (_local_10 * _local_7.x)) - _local_8.x), ((_local_4.y + (_local_10 * _local_7.y)) - _local_8.y)) == RoomPlaneParser.TILE_HOLE) + { + if(((_local_10 > 0) && (_local_9 == 0))) + { + k._Str_24531(_local_3, _local_10); + break; + } + _local_9++; + } + else + { + if(_local_9 > 0) + { + k._Str_23976(_local_3, _local_9); + break; + } + } + _local_10++; + } + if(_local_9 == _local_6) + { + k._Str_15901(_local_3, true); + } + } + _local_3++; + } + } + + private resolveOriginalWallIndex(k: Point, _arg_2: Point, _arg_3: RoomWallData): number + { + let _local_10: Point; + let _local_11: Point; + let _local_12: number; + let _local_13: number; + let _local_14: number; + let _local_15: number; + const _local_4: number = Math.min(k.y, _arg_2.y); + const _local_5: number = Math.max(k.y, _arg_2.y); + const _local_6: number = Math.min(k.x, _arg_2.x); + const _local_7: number = Math.max(k.x, _arg_2.x); + const _local_8: number = _arg_3.count; + let _local_9 = 0; + while(_local_9 < _local_8) + { + _local_10 = _arg_3._Str_10778(_local_9); + _local_11 = _arg_3._Str_19138(_local_9); + if(k.x == _arg_2.x) + { + if(((_local_10.x == k.x) && (_local_11.x == k.x))) + { + _local_12 = Math.min(_local_10.y, _local_11.y); + _local_13 = Math.max(_local_10.y, _local_11.y); + if(((_local_12 <= _local_4) && (_local_5 <= _local_13))) + { + return _local_9; + } + } + } + else + { + if(k.y == _arg_2.y) + { + if(((_local_10.y == k.y) && (_local_11.y == k.y))) + { + _local_14 = Math.min(_local_10.x, _local_11.x); + _local_15 = Math.max(_local_10.x, _local_11.x); + if(((_local_14 <= _local_6) && (_local_7 <= _local_15))) + { + return _local_9; + } + } + } + } + _local_9++; + } + return -1; + } + + private hideOriginallyHiddenWalls(k: RoomWallData, _arg_2: RoomWallData): void + { + let _local_5: Point; + let _local_6: Point; + let _local_7: IVector3D; + let _local_8: number; + let _local_9: number; + const _local_3: number = k.count; + let _local_4 = 0; + while(_local_4 < _local_3) + { + if(!k._Str_10019(_local_4)) + { + _local_5 = k._Str_10778(_local_4); + _local_6 = new Point(_local_5.x, _local_5.y); + _local_7 = RoomWallData.WALL_DIRECTION_VECTORS[k.getDirection(_local_4)]; + _local_8 = k._Str_13743(_local_4); + _local_6.x = (_local_6.x + (_local_7.x * _local_8)); + _local_6.y = (_local_6.y + (_local_7.y * _local_8)); + _local_9 = this.resolveOriginalWallIndex(_local_5, _local_6, _arg_2); + if(_local_9 >= 0) + { + if(_arg_2._Str_10019(_local_9)) + { + k._Str_15901(_local_4, true); + } + } + else + { + k._Str_15901(_local_4, true); + } + } + _local_4++; + } + } + + private checkWallHiding(k: RoomWallData, _arg_2: RoomWallData): void + { + this.hidePeninsulaWallChains(_arg_2); + this.updateWallsNextToHoles(k); + this.hideOriginallyHiddenWalls(k, _arg_2); + } + + private addWalls(k: RoomWallData, _arg_2: RoomWallData): void + { + const _local_3 = k.count; + const _local_4 = _arg_2.count; + let _local_7 = 0; + + while(_local_7 < _local_3) + { + if(!k._Str_10019(_local_7)) + { + const _local_8 = k._Str_10778(_local_7); + const _local_9 = k.getDirection(_local_7); + const _local_10 = k._Str_13743(_local_7); + const _local_11 = RoomWallData.WALL_DIRECTION_VECTORS[_local_9]; + const _local_12 = RoomWallData.WALL_NORMAL_VECTORS[_local_9]; + let _local_13 = -1; + let _local_14 = 0; + + while(_local_14 < _local_10) + { + const _local_27 = this.getTileHeightInternal(((_local_8.x + (_local_14 * _local_11.x)) + _local_12.x), ((_local_8.y + (_local_14 * _local_11.y)) + _local_12.y)); + + if(((_local_27 >= 0) && ((_local_27 < _local_13) || (_local_13 < 0)))) + { + _local_13 = _local_27; + } + + _local_14++; + } + + const _local_15 = _local_13; + + let _local_16 = new Vector3d(_local_8.x, _local_8.y, _local_15); + _local_16 = Vector3d.sum(_local_16, Vector3d.product(_local_12, 0.5)); + _local_16 = Vector3d.sum(_local_16, Vector3d.product(_local_11, -0.5)); + + const _local_17 = ((this.wallHeight + Math.min(RoomPlaneParser.MAX_WALL_ADDITIONAL_HEIGHT, this.floorHeight)) - _local_13); + const _local_18 = Vector3d.product(_local_11, -(_local_10)); + const _local_19 = new Vector3d(0, 0, _local_17); + + _local_16 = Vector3d.dif(_local_16, _local_18); + + const _local_20 = this.resolveOriginalWallIndex(_local_8, k._Str_19138(_local_7), _arg_2); + + let _local_5 = 0; + let _local_6 = 0; + + if(_local_20 >= 0) + { + _local_5 = _arg_2.getDirection(((_local_20 + 1) % _local_4)); + _local_6 = _arg_2.getDirection((((_local_20 - 1) + _local_4) % _local_4)); + } + else + { + _local_5 = k.getDirection(((_local_7 + 1) % _local_3)); + _local_6 = k.getDirection((((_local_7 - 1) + _local_3) % _local_3)); + } + + let _local_21 = null; + + if((((_local_5 - _local_9) + 4) % 4) == 3) + { + _local_21 = RoomWallData.WALL_NORMAL_VECTORS[_local_5]; + } + else + { + if((((_local_9 - _local_6) + 4) % 4) == 3) + { + _local_21 = RoomWallData.WALL_NORMAL_VECTORS[_local_6]; + } + } + + const _local_22 = k._Str_17084(_local_7); + const _local_23 = k._Str_17084((((_local_7 - 1) + _local_3) % _local_3)); + const _local_24 = k._Str_10019(((_local_7 + 1) % _local_3)); + const _local_25 = k._Str_25455(_local_7); + const _local_26 = k._Str_24163(_local_7); + + this.addWall(_local_16, _local_18, _local_19, _local_21, ((!(_local_23)) || (_local_25)), ((!(_local_22)) || (_local_26)), (!(_local_24))); + } + + _local_7++; + } + } + + private createWallPlanes(): boolean + { + let _local_13: number; + let _local_14: number; + const k = this._tileMatrix; + if(k == null) + { + return false; + } + let _local_2: number; + let _local_3: number; + let _local_4: number[]; + const _local_5: number = k.length; + let _local_6 = 0; + if(_local_5 == 0) + { + return false; + } + _local_2 = 0; + while(_local_2 < _local_5) + { + _local_4 = k[_local_2]; + if(((_local_4 == null) || (_local_4.length == 0))) + { + return false; + } + if(_local_6 > 0) + { + _local_6 = Math.min(_local_6, _local_4.length); + } + else + { + _local_6 = _local_4.length; + } + _local_2++; + } + const _local_7: number = Math.min(RoomPlaneParser.MAX_WALL_ADDITIONAL_HEIGHT, ((this._fixedWallHeight != -1) ? this._fixedWallHeight : RoomPlaneParser.getFloorHeight(k))); + const _local_8: number = this.minX; + let _local_9: number = this.minY; + _local_9 = this.minY; + while(_local_9 <= this.maxY) + { + if(this.getTileHeightInternal(_local_8, _local_9) > RoomPlaneParser.TILE_HOLE) + { + _local_9--; + break; + } + _local_9++; + } + if(_local_9 > this.maxY) + { + return false; + } + const _local_10: Point = new Point(_local_8, _local_9); + const _local_11: RoomWallData = this.generateWallData(_local_10, true); + const _local_12: RoomWallData = this.generateWallData(_local_10, false); + if(_local_11 != null) + { + _local_13 = _local_11.count; + _local_14 = _local_12.count; + this.checkWallHiding(_local_11, _local_12); + this.addWalls(_local_11, _local_12); + } + _local_3 = 0; + while(_local_3 < this.tileMapHeight) + { + _local_2 = 0; + while(_local_2 < this.tileMapWidth) + { + if(this.getTileHeightInternal(_local_2, _local_3) < 0) + { + this.setTileHeight(_local_2, _local_3, -(_local_7 + this.wallHeight)); + } + _local_2++; + } + _local_3++; + } + return true; + } + + private extractTopWall(k: Point, _arg_2: boolean): Point + { + if(k == null) + { + return null; + } + let _local_3 = 1; + let _local_4: number = RoomPlaneParser.TILE_HOLE; + if(!_arg_2) + { + _local_4 = RoomPlaneParser.TILE_BLOCKED; + } + while(_local_3 < 1000) + { + if(this.getTileHeightInternal((k.x + _local_3), k.y) > _local_4) + { + return new Point(((k.x + _local_3) - 1), k.y); + } + if(this.getTileHeightInternal((k.x + _local_3), (k.y + 1)) <= _local_4) + { + return new Point((k.x + _local_3), (k.y + 1)); + } + _local_3++; + } + return null; + } + + private extractRightWall(k: Point, _arg_2: boolean): Point + { + if(k == null) + { + return null; + } + let _local_3 = 1; + let _local_4: number = RoomPlaneParser.TILE_HOLE; + if(!_arg_2) + { + _local_4 = RoomPlaneParser.TILE_BLOCKED; + } + while(_local_3 < 1000) + { + if(this.getTileHeightInternal(k.x, (k.y + _local_3)) > _local_4) + { + return new Point(k.x, (k.y + (_local_3 - 1))); + } + if(this.getTileHeightInternal((k.x - 1), (k.y + _local_3)) <= _local_4) + { + return new Point((k.x - 1), (k.y + _local_3)); + } + _local_3++; + } + return null; + } + + private extractBottomWall(k: Point, _arg_2: boolean): Point + { + if(k == null) + { + return null; + } + let _local_3 = 1; + let _local_4: number = RoomPlaneParser.TILE_HOLE; + if(!_arg_2) + { + _local_4 = RoomPlaneParser.TILE_BLOCKED; + } + while(_local_3 < 1000) + { + if(this.getTileHeightInternal((k.x - _local_3), k.y) > _local_4) + { + return new Point((k.x - (_local_3 - 1)), k.y); + } + if(this.getTileHeightInternal((k.x - _local_3), (k.y - 1)) <= _local_4) + { + return new Point((k.x - _local_3), (k.y - 1)); + } + _local_3++; + } + return null; + } + + private extractLeftWall(k: Point, _arg_2: boolean): Point + { + if(k == null) + { + return null; + } + let _local_3 = 1; + let _local_4: number = RoomPlaneParser.TILE_HOLE; + if(!_arg_2) + { + _local_4 = RoomPlaneParser.TILE_BLOCKED; + } + while(_local_3 < 1000) + { + if(this.getTileHeightInternal(k.x, (k.y - _local_3)) > _local_4) + { + return new Point(k.x, (k.y - (_local_3 - 1))); + } + if(this.getTileHeightInternal((k.x + 1), (k.y - _local_3)) <= _local_4) + { + return new Point((k.x + 1), (k.y - _local_3)); + } + _local_3++; + } + return null; + } + + private addWall(k: IVector3D, _arg_2: IVector3D, _arg_3: IVector3D, _arg_4: IVector3D, _arg_5: boolean, _arg_6: boolean, _arg_7: boolean): void + { + this.addPlane(RoomPlaneData.PLANE_WALL, k, _arg_2, _arg_3, [_arg_4]); + //this.addPlane(RoomPlaneData.PLANE_LANDSCAPE, k, _arg_2, _arg_3, [_arg_4]); + const _local_8: number = (RoomPlaneParser.WALL_THICKNESS * this._wallThicknessMultiplier); + const _local_9: number = (RoomPlaneParser.FLOOR_THICKNESS * this._floorThicknessMultiplier); + const _local_10:Vector3d = Vector3d.crossProduct(_arg_2, _arg_3); + const _local_11:Vector3d = Vector3d.product(_local_10, ((1 / _local_10.length) * -(_local_8))); + this.addPlane(RoomPlaneData.PLANE_WALL, Vector3d.sum(k, _arg_3), _arg_2, _local_11, [_local_10, _arg_4]); + if(_arg_5) + { + this.addPlane(RoomPlaneData.PLANE_WALL, Vector3d.sum(Vector3d.sum(k, _arg_2), _arg_3), Vector3d.product(_arg_3, (-(_arg_3.length + _local_9) / _arg_3.length)), _local_11, [_local_10, _arg_4]); + } + if(_arg_6) + { + this.addPlane(RoomPlaneData.PLANE_WALL, Vector3d.sum(k, Vector3d.product(_arg_3, (-(_local_9) / _arg_3.length))), Vector3d.product(_arg_3, ((_arg_3.length + _local_9) / _arg_3.length)), _local_11, [_local_10, _arg_4]); + if(_arg_7) + { + const _local_12 = Vector3d.product(_arg_2, (_local_8 / _arg_2.length)); + this.addPlane(RoomPlaneData.PLANE_WALL, Vector3d.sum(Vector3d.sum(k, _arg_3), Vector3d.product(_local_12, -1)), _local_12, _local_11, [_local_10, _arg_2, _arg_4]); + } + } + } + + private addFloor(k: IVector3D, _arg_2: IVector3D, _arg_3: IVector3D, _arg_4: boolean, _arg_5: boolean, _arg_6: boolean, _arg_7: boolean): void + { + let _local_9: number; + let _local_10:Vector3d; + let _local_11:Vector3d; + const _local_8: RoomPlaneData = this.addPlane(RoomPlaneData.PLANE_FLOOR, k, _arg_2, _arg_3); + if(_local_8 != null) + { + _local_9 = (RoomPlaneParser.FLOOR_THICKNESS * this._floorThicknessMultiplier); + _local_10 = new Vector3d(0, 0, _local_9); + _local_11 = Vector3d.dif(k, _local_10); + if(_arg_6) + { + this.addPlane(RoomPlaneData.PLANE_FLOOR, _local_11, _arg_2, _local_10); + } + if(_arg_7) + { + this.addPlane(RoomPlaneData.PLANE_FLOOR, Vector3d.sum(_local_11, Vector3d.sum(_arg_2, _arg_3)), Vector3d.product(_arg_2, -1), _local_10); + } + if(_arg_4) + { + this.addPlane(RoomPlaneData.PLANE_FLOOR, Vector3d.sum(_local_11, _arg_3), Vector3d.product(_arg_3, -1), _local_10); + } + if(_arg_5) + { + this.addPlane(RoomPlaneData.PLANE_FLOOR, Vector3d.sum(_local_11, _arg_2), _arg_3, _local_10); + } + } + } + + public initializeFromMapData(data: RoomMapData): boolean + { + if(!data) return false; + + this.reset(); + + this.resetFloorHoles(); + + const width = data.width; + const height = data.height; + const wallHeight = data.wallHeight; + const fixedWallsHeight = data.fixedWallsHeight; + + this.initializeTileMap(width, height); + + if(data.tileMap) + { + let y = 0; + + while(y < data.tileMap.length) + { + const row = data.tileMap[y]; + + if(row) + { + let x = 0; + + while(x < row.length) + { + const column = row[x]; + + if(column) this.setTileHeight(x, y, column.height); + + x++; + } + } + + y++; + } + } + + if(data.holeMap && data.holeMap.length) + { + let index = 0; + + while(index < data.holeMap.length) + { + const hole = data.holeMap[index]; + + if(!hole) continue; + + this.addFloorHole(hole.id, hole.x, hole.y, hole.width, hole.height); + + index++; + } + + this.initializeHoleMap(); + } + + this.wallHeight = wallHeight; + this.restrictsDragging = data.restrictsDragging; + this.restrictsScaling = data.restrictsScaling; + this.restrictedScale = data.restrictedScale; + + this.initializeFromTileData(fixedWallsHeight); + + return true; + } + + private addPlane(k: number, _arg_2: IVector3D, _arg_3: IVector3D, _arg_4: IVector3D, _arg_5: IVector3D[] = null): RoomPlaneData + { + if(((_arg_3.length == 0) || (_arg_4.length == 0))) + { + return null; + } + const _local_6: RoomPlaneData = new RoomPlaneData(k, _arg_2, _arg_3, _arg_4, _arg_5); + this._planes.push(_local_6); + return _local_6; + } + + public getMapData(): RoomMapData + { + const data = new RoomMapData(); + + data.width = this._width; + data.height = this._height; + data.wallHeight = this._wallHeight; + data.fixedWallsHeight = this._fixedWallHeight; + data.dimensions.minX = this.minX; + data.dimensions.maxX = this.maxX; + data.dimensions.minY = this.minY; + data.dimensions.maxY = this.maxY; + data.restrictsDragging = this.restrictsDragging; + data.restrictsScaling = this.restrictsScaling; + data.restrictedScale = this.restrictedScale; + + let y = 0; + + while(y < this._height) + { + const tileRow: { height: number }[] = []; + const tileMatrix = this._tileMatrixOriginal[y]; + + let x = 0; + + while(x < this._width) + { + const tileHeight = tileMatrix[x]; + + tileRow.push({ height: tileHeight }); + + x++; + } + + data.tileMap.push(tileRow); + + y++; + } + + for(const [ holeId, holeData ] of this._floorHoles.entries()) + { + if(!holeData) continue; + + data.holeMap.push({ + id: holeId, + x: holeData.x, + y: holeData.y, + width: holeData.width, + height: holeData.height + }); + } + + return data; + } + + public getPlaneLocation(k: number): IVector3D + { + if(((k < 0) || (k >= this.planeCount))) return null; + + const planeData = this._planes[k]; + + if(!planeData) return null; + + return planeData.loc; + } + + public getPlaneNormal(k: number): IVector3D + { + if(((k < 0) || (k >= this.planeCount))) return null; + + const planeData = this._planes[k]; + + if(!planeData) return null; + + return planeData.normal; + } + + public getPlaneLeftSide(k: number): IVector3D + { + if(((k < 0) || (k >= this.planeCount))) return null; + + const planeData = this._planes[k]; + + if(!planeData) return null; + + return planeData._Str_5424; + } + + public getPlaneRightSide(k: number): IVector3D + { + if(((k < 0) || (k >= this.planeCount))) return null; + + const planeData = this._planes[k]; + + if(!planeData) return null; + + return planeData._Str_4968; + } + + public getPlaneNormalDirection(k: number): IVector3D + { + if(((k < 0) || (k >= this.planeCount))) return null; + + const planeData = this._planes[k]; + + if(!planeData) return null; + + return planeData._Str_25207; + } + + public getPlaneSecondaryNormals(k: number): IVector3D[] + { + let _local_3: IVector3D[]; + let _local_4: number; + if(((k < 0) || (k >= this.planeCount))) + { + return null; + } + const _local_2: RoomPlaneData = (this._planes[k] as RoomPlaneData); + if(_local_2 != null) + { + _local_3 = []; + _local_4 = 0; + while(_local_4 < _local_2._Str_20277) + { + _local_3.push(_local_2._Str_22585(_local_4)); + _local_4++; + } + return _local_3; + } + return null; + } + + public getPlaneType(k: number): number + { + if(((k < 0) || (k >= this.planeCount))) return RoomPlaneData.PLANE_UNDEFINED; + + const planeData = this._planes[k]; + + if(!planeData) return RoomPlaneData.PLANE_UNDEFINED; + + return planeData.type; + } + + public getPlaneMaskCount(k: number): number + { + if(((k < 0) || (k >= this.planeCount))) return 0; + + const planeData = this._planes[k]; + + if(!planeData) return 0; + + return planeData._Str_6845; + } + + public getPlaneMaskLeftSideLoc(k: number, _arg_2: number): number + { + if(((k < 0) || (k >= this.planeCount))) return -1; + + const planeData = this._planes[k]; + + if(!planeData) return -1; + + return planeData._Str_25133(_arg_2); + } + + public getPlaneMaskRightSideLoc(k: number, _arg_2: number): number + { + if(((k < 0) || (k >= this.planeCount))) return -1; + + const planeData = this._planes[k]; + + if(!planeData) return -1; + + return planeData._Str_23609(_arg_2); + } + + public getPlaneMaskLeftSideLength(k: number, _arg_2: number): number + { + if(((k < 0) || (k >= this.planeCount))) return -1; + + const planeData = this._planes[k]; + + if(!planeData) return -1; + + return planeData._Str_25097(_arg_2); + } + + public getPlaneMaskRightSideLength(k: number, _arg_2: number): number + { + if(((k < 0) || (k >= this.planeCount))) return -1; + + const planeData = this._planes[k]; + + if(!planeData) return -1; + + return planeData._Str_25617(_arg_2); + } + + public addFloorHole(k: number, _arg_2: number, _arg_3: number, _arg_4: number, _arg_5: number): void + { + this.removeFloorHole(k); + + this._floorHoles.set(k, new RoomFloorHole(_arg_2, _arg_3, _arg_4, _arg_5)); + } + + public removeFloorHole(k: number): void + { + this._floorHoles.delete(k); + } + + public resetFloorHoles(): void + { + this._floorHoles.clear(); + } + + private initializeHoleMap(): void + { + let k: number; + let _local_2: number; + let _local_3: boolean[]; + let _local_5:RoomFloorHole; + let _local_6: number; + let _local_7: number; + let _local_8: number; + let _local_9: number; + _local_2 = 0; + while(_local_2 < this._height) + { + _local_3 = this._floorHoleMatrix[_local_2]; + k = 0; + while(k < this._width) + { + _local_3[k] = false; + k++; + } + _local_2++; + } + for(const _local_4 of this._floorHoles.values()) + { + _local_5 = _local_4; + if(_local_5 != null) + { + _local_6 = _local_5.x; + _local_7 = ((_local_5.x + _local_5.width) - 1); + _local_8 = _local_5.y; + _local_9 = ((_local_5.y + _local_5.height) - 1); + _local_6 = ((_local_6 < 0) ? 0 : _local_6); + _local_7 = ((_local_7 >= this._width) ? (this._width - 1) : _local_7); + _local_8 = ((_local_8 < 0) ? 0 : _local_8); + _local_9 = ((_local_9 >= this._height) ? (this._height - 1) : _local_9); + _local_2 = _local_8; + while(_local_2 <= _local_9) + { + _local_3 = this._floorHoleMatrix[_local_2]; + k = _local_6; + while(k <= _local_7) + { + _local_3[k] = true; + k++; + } + _local_2++; + } + } + } + } + + private extractPlanes(k: number[][]): void + { + let _local_7: number; + let _local_8: number; + let _local_9: number; + let _local_10: number; + let _local_11: boolean; + let _local_12: boolean; + let _local_13: boolean; + let _local_14: boolean; + let _local_15: number; + let _local_16: number; + let _local_17: boolean; + let _local_18: number; + let _local_19: number; + let _local_20: number; + let _local_21: number; + + const _local_2 = k.length; + + const _local_3: number = k[0].length; + const _local_4: boolean[][] = []; + let _local_5 = 0; + while(_local_5 < _local_2) + { + _local_4[_local_5] = []; + _local_5++; + } + let _local_6 = 0; + while(_local_6 < _local_2) + { + _local_7 = 0; + while(_local_7 < _local_3) + { + _local_8 = k[_local_6][_local_7]; + if(((_local_8 < 0) || (_local_4[_local_6][_local_7]))) + { + // + } + else + { + _local_11 = ((_local_7 == 0) || (!(k[_local_6][(_local_7 - 1)] == _local_8))); + _local_12 = ((_local_6 == 0) || (!(k[(_local_6 - 1)][_local_7] == _local_8))); + _local_9 = (_local_7 + 1); + while(_local_9 < _local_3) + { + if((((!(k[_local_6][_local_9] == _local_8)) || (_local_4[_local_6][_local_9])) || ((_local_6 > 0) && ((k[(_local_6 - 1)][_local_9] == _local_8) == _local_12)))) + { + break; + } + _local_9++; + } + _local_13 = ((_local_9 == _local_3) || (!(k[_local_6][_local_9] == _local_8))); + _local_17 = false; + _local_10 = (_local_6 + 1); + while(((_local_10 < _local_2) && (!(_local_17)))) + { + _local_14 = (!(k[_local_10][_local_7] == _local_8)); + _local_17 = (((_local_14) || ((_local_7 > 0) && ((k[_local_10][(_local_7 - 1)] == _local_8) == _local_11))) || ((_local_9 < _local_3) && ((k[_local_10][_local_9] == _local_8) == _local_13))); + _local_15 = _local_7; + while(_local_15 < _local_9) + { + if((k[_local_10][_local_15] == _local_8) == _local_14) + { + _local_17 = true; + _local_9 = _local_15; + break; + } + _local_15++; + } + if(_local_17) + { + break; + } + _local_10++; + } + _local_14 = ((_local_14) || (_local_10 == _local_2)); + _local_13 = ((_local_9 == _local_3) || (!(k[_local_6][_local_9] == _local_8))); + _local_16 = _local_6; + while(_local_16 < _local_10) + { + _local_15 = _local_7; + while(_local_15 < _local_9) + { + _local_4[_local_16][_local_15] = true; + _local_15++; + } + _local_16++; + } + _local_18 = ((_local_7 / 4) - 0.5); + _local_19 = ((_local_6 / 4) - 0.5); + _local_20 = ((_local_9 - _local_7) / 4); + _local_21 = ((_local_10 - _local_6) / 4); + this.addFloor(new Vector3d((_local_18 + _local_20), (_local_19 + _local_21), (_local_8 / 4)), new Vector3d(-(_local_20), 0, 0), new Vector3d(0, -(_local_21), 0), _local_13, _local_11, _local_14, _local_12); + } + _local_7++; + } + _local_6++; + } + } + + public get restrictsDragging(): boolean + { + return this._restrictsDragging; + } + + public set restrictsDragging(flag: boolean) + { + this._restrictsDragging = flag; + } + + public get restrictsScaling(): boolean + { + return this._restrictsScaling; + } + + public set restrictsScaling(flag: boolean) + { + this._restrictsScaling = flag; + } + + public get restrictedScale(): number + { + return this._restrictedScale; + } + + public set restrictedScale(scale: number) + { + this._restrictedScale = scale; + } +} \ No newline at end of file diff --git a/src/nitro/room/object/RoomWallData.ts b/src/nitro/room/object/RoomWallData.ts new file mode 100644 index 00000000..24131ffc --- /dev/null +++ b/src/nitro/room/object/RoomWallData.ts @@ -0,0 +1,182 @@ +import { Point } from 'pixi.js'; +import { IVector3D } from '../../../room/utils/IVector3D'; +import { Vector3d } from '../../../room/utils/Vector3d'; + +export class RoomWallData +{ + public static WALL_DIRECTION_VECTORS: Vector3d[] = [ + new Vector3d(1, 0, 0), + new Vector3d(0, 1, 0), + new Vector3d(-1, 0, 0), + new Vector3d(0, -1, 0) + ]; + + public static WALL_NORMAL_VECTORS: Vector3d[] = [ + new Vector3d(0, 1, 0), + new Vector3d(-1, 0, 0), + new Vector3d(0, -1, 0), + new Vector3d(1, 0, 0) + ]; + + private _corners: Point[]; + private _endPoints: Point[]; + private _directions: number[]; + private _lengths: number[]; + private _leftTurns: boolean[]; + private _borders: boolean[]; + private _hideWalls: boolean[]; + private _manuallyLeftCut: boolean[]; + private _manuallyRightCut: boolean[]; + private _addDuplicates: boolean; + private _count: number; + + constructor() + { + this._corners = []; + this._endPoints = []; + this._directions = []; + this._lengths = []; + this._leftTurns = []; + this._borders = []; + this._hideWalls = []; + this._manuallyLeftCut = []; + this._manuallyRightCut = []; + this._addDuplicates = false; + this._count = 0; + } + + public _Str_17862(k: Point, _arg_2: number, _arg_3: number, _arg_4: boolean, _arg_5: boolean): void + { + if(((this._addDuplicates) || (this._Str_22484(k, _arg_2, _arg_3, _arg_4, _arg_5)))) + { + this._corners.push(k); + this._directions.push(_arg_2); + this._lengths.push(_arg_3); + this._borders.push(_arg_4); + this._leftTurns.push(_arg_5); + this._hideWalls.push(false); + this._manuallyLeftCut.push(false); + this._manuallyRightCut.push(false); + this._count++; + } + } + + private _Str_22484(k: Point, _arg_2: number, _arg_3: number, _arg_4: boolean, _arg_5: boolean): boolean + { + let _local_6 = 0; + + while(_local_6 < this._count) + { + if(((((((this._corners[_local_6].x == k.x) && (this._corners[_local_6].y == k.y)) && (this._directions[_local_6] == _arg_2)) && (this._lengths[_local_6] == _arg_3)) && (this._borders[_local_6] == _arg_4)) && (this._leftTurns[_local_6] == _arg_5))) + { + return false; + } + _local_6++; + } + return true; + } + + public get count(): number + { + return this._count; + } + + public _Str_10778(k: number): Point + { + return this._corners[k]; + } + + public _Str_19138(k: number): Point + { + this._Str_23674(); + return this._endPoints[k]; + } + + public _Str_13743(k: number): number + { + return this._lengths[k]; + } + + public getDirection(k: number): number + { + return this._directions[k]; + } + + public _Str_25208(k: number): boolean + { + return this._borders[k]; + } + + public _Str_10019(k: number): boolean + { + return this._hideWalls[k]; + } + + public _Str_17084(k: number): boolean + { + return this._leftTurns[k]; + } + + public _Str_25455(k: number): boolean + { + return this._manuallyLeftCut[k]; + } + + public _Str_24163(k: number): boolean + { + return this._manuallyRightCut[k]; + } + + public _Str_15901(k: number, _arg_2: boolean): void + { + this._hideWalls[k] = _arg_2; + } + + public _Str_24531(k: number, _arg_2: number): void + { + if(_arg_2 < this._lengths[k]) + { + this._lengths[k] = _arg_2; + this._manuallyRightCut[k] = true; + } + } + + public _Str_23976(k: number, _arg_2: number): void + { + let _local_3: IVector3D; + if(((_arg_2 > 0) && (_arg_2 < this._lengths[k]))) + { + const corner = this._corners[k]; + + _local_3 = RoomWallData.WALL_DIRECTION_VECTORS[this.getDirection(k)]; + this._corners[k] = new Point((corner.x + (_arg_2 * _local_3.x)), (corner.y + (_arg_2 * _local_3.y))); + this._lengths[k] = (this._lengths[k] - _arg_2); + this._manuallyLeftCut[k] = true; + } + } + + private _Str_23674(): void + { + let k: number; + let _local_2: Point; + let _local_3: Point; + let _local_4:IVector3D; + let _local_5: number; + if(this._endPoints.length != this.count) + { + this._endPoints = []; + k = 0; + while(k < this.count) + { + _local_2 = this._Str_10778(k); + _local_3 = new Point(_local_2.x, _local_2.y); + _local_4 = RoomWallData.WALL_DIRECTION_VECTORS[this.getDirection(k)]; + _local_5 = this._Str_13743(k); + _local_3.x = (_local_3.x + (_local_4.x * _local_5)); + _local_3.y = (_local_3.y + (_local_4.y * _local_5)); + this._endPoints.push(_local_3); + k++; + } + } + } +} \ No newline at end of file diff --git a/src/nitro/room/object/data/IObjectData.ts b/src/nitro/room/object/data/IObjectData.ts new file mode 100644 index 00000000..f158baad --- /dev/null +++ b/src/nitro/room/object/data/IObjectData.ts @@ -0,0 +1,16 @@ +import { IMessageDataWrapper } from '../../../../core/communication/messages/IMessageDataWrapper'; +import { IRoomObjectModel } from '../../../../room/object/IRoomObjectModel'; + +export interface IObjectData +{ + state: number; + isUnique: boolean; + uniqueNumber: number; + uniqueSeries: number; + flags: number; + parseWrapper(wrapper: IMessageDataWrapper): void; + initializeFromRoomObjectModel(model: IRoomObjectModel): void; + writeRoomObjectModel(model: IRoomObjectModel): void; + getLegacyString(): string; + compare(data: IObjectData): boolean; +} \ No newline at end of file diff --git a/src/nitro/room/object/data/ObjectDataBase.ts b/src/nitro/room/object/data/ObjectDataBase.ts new file mode 100644 index 00000000..f04d41f6 --- /dev/null +++ b/src/nitro/room/object/data/ObjectDataBase.ts @@ -0,0 +1,84 @@ +import { IMessageDataWrapper } from '../../../../core/communication/messages/IMessageDataWrapper'; +import { IRoomObjectModel } from '../../../../room/object/IRoomObjectModel'; +import { RoomObjectVariable } from '../RoomObjectVariable'; +import { IObjectData } from './IObjectData'; +import { ObjectDataFlags } from './ObjectDataFlags'; + +export class ObjectDataBase implements IObjectData +{ + private _flags: number; + private _uniqueNumber: number; + private _uniqueSeries: number; + + constructor() + { + this._flags = 0; + this._uniqueNumber = 0; + this._uniqueSeries = 0; + } + + public parseWrapper(wrapper: IMessageDataWrapper): void + { + if((this._flags & ObjectDataFlags.UNIQUE_SET) > 0) + { + this._uniqueNumber = wrapper.readInt(); + this._uniqueSeries = wrapper.readInt(); + } + } + + public initializeFromRoomObjectModel(model: IRoomObjectModel): void + { + this._uniqueNumber = model.getValue(RoomObjectVariable.FURNITURE_UNIQUE_SERIAL_NUMBER); + this._uniqueSeries = model.getValue(RoomObjectVariable.FURNITURE_UNIQUE_EDITION_SIZE); + } + + public writeRoomObjectModel(model: IRoomObjectModel): void + { + if(!model) return; + + model.setValue(RoomObjectVariable.FURNITURE_UNIQUE_SERIAL_NUMBER, this._uniqueNumber); + model.setValue(RoomObjectVariable.FURNITURE_UNIQUE_EDITION_SIZE, this._uniqueSeries); + } + + public getLegacyString(): string + { + return ''; + } + + public compare(data: IObjectData): boolean + { + return false; + } + + public get state(): number + { + const state = parseInt(this.getLegacyString()); + + return isNaN(state) ? 0 : state; + } + + public get isUnique(): boolean + { + return this._uniqueSeries > 0; + } + + public get uniqueNumber(): number + { + return this._uniqueNumber; + } + + public get uniqueSeries(): number + { + return this._uniqueSeries; + } + + public get flags(): number + { + return this._flags; + } + + public set flags(flags: number) + { + this._flags = flags; + } +} \ No newline at end of file diff --git a/src/nitro/room/object/data/ObjectDataFactory.ts b/src/nitro/room/object/data/ObjectDataFactory.ts new file mode 100644 index 00000000..aae0c149 --- /dev/null +++ b/src/nitro/room/object/data/ObjectDataFactory.ts @@ -0,0 +1,51 @@ +import { IObjectData } from './IObjectData'; +import { CrackableDataType } from './type/CrackableDataType'; +import { EmptyDataType } from './type/EmptyDataType'; +import { HighScoreDataType } from './type/HighScoreDataType'; +import { LegacyDataType } from './type/LegacyDataType'; +import { MapDataType } from './type/MapDataType'; +import { NumberDataType } from './type/NumberDataType'; +import { StringDataType } from './type/StringDataType'; +import { VoteDataType } from './type/VoteDataType'; + +export class ObjectDataFactory +{ + public static getData(flags: number): IObjectData + { + let objectData: IObjectData = null; + + switch(flags & 0xFF) + { + case CrackableDataType.FORMAT_KEY: + objectData = new CrackableDataType(); + break; + case EmptyDataType.FORMAT_KEY: + objectData = new EmptyDataType(); + break; + case HighScoreDataType.FORMAT_KEY: + objectData = new HighScoreDataType(); + break; + case LegacyDataType.FORMAT_KEY: + objectData = new LegacyDataType(); + break; + case MapDataType.FORMAT_KEY: + objectData = new MapDataType(); + break; + case NumberDataType.FORMAT_KEY: + objectData = new NumberDataType(); + break; + case StringDataType.FORMAT_KEY: + objectData = new StringDataType(); + break; + case VoteDataType.FORMAT_KEY: + objectData = new VoteDataType(); + break; + } + + if(!objectData) return null; + + objectData.flags = (flags & 0xFF00); + + return objectData; + } +} \ No newline at end of file diff --git a/src/nitro/room/object/data/ObjectDataFlags.ts b/src/nitro/room/object/data/ObjectDataFlags.ts new file mode 100644 index 00000000..bbcd44b2 --- /dev/null +++ b/src/nitro/room/object/data/ObjectDataFlags.ts @@ -0,0 +1,4 @@ +export class ObjectDataFlags +{ + public static UNIQUE_SET = 256; +} \ No newline at end of file diff --git a/src/nitro/room/object/data/ObjectDataKey.ts b/src/nitro/room/object/data/ObjectDataKey.ts new file mode 100644 index 00000000..ea5bd0b2 --- /dev/null +++ b/src/nitro/room/object/data/ObjectDataKey.ts @@ -0,0 +1,11 @@ +export class ObjectDataKey +{ + public static LEGACY_KEY: number = 0; + public static MAP_KEY: number = 1; + public static STRING_KEY: number = 2; + public static VOTE_KEY: number = 3; + public static EMPTY_KEY: number = 4; + public static NUMBER_KEY: number = 5; + public static HIGHSCORE_KEY: number = 6; + public static CRACKABLE_KEY: number = 7; +} \ No newline at end of file diff --git a/src/nitro/room/object/data/type/CrackableDataType.ts b/src/nitro/room/object/data/type/CrackableDataType.ts new file mode 100644 index 00000000..0e32561c --- /dev/null +++ b/src/nitro/room/object/data/type/CrackableDataType.ts @@ -0,0 +1,74 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IRoomObjectModel } from '../../../../../room/object/IRoomObjectModel'; +import { RoomObjectVariable } from '../../RoomObjectVariable'; +import { IObjectData } from '../IObjectData'; +import { ObjectDataBase } from '../ObjectDataBase'; +import { ObjectDataKey } from '../ObjectDataKey'; + +export class CrackableDataType extends ObjectDataBase implements IObjectData +{ + public static FORMAT_KEY = ObjectDataKey.CRACKABLE_KEY; + + private _state: string; + private _hits: number; + private _target: number; + + constructor() + { + super(); + + this._state = ''; + this._hits = 0; + this._target = 0; + } + + public parseWrapper(wrapper: IMessageDataWrapper): void + { + if(!wrapper) return; + + this._state = wrapper.readString(); + this._hits = wrapper.readInt(); + this._target = wrapper.readInt(); + + super.parseWrapper(wrapper); + } + + public initializeFromRoomObjectModel(model: IRoomObjectModel): void + { + super.initializeFromRoomObjectModel(model); + + this._state = model.getValue(RoomObjectVariable.FURNITURE_CRACKABLE_STATE); + this._hits = model.getValue(RoomObjectVariable.FURNITURE_CRACKABLE_HITS); + this._target = model.getValue(RoomObjectVariable.FURNITURE_CRACKABLE_TARGET); + } + + public writeRoomObjectModel(model: IRoomObjectModel): void + { + super.writeRoomObjectModel(model); + + model.setValue(RoomObjectVariable.FURNITURE_DATA_FORMAT, CrackableDataType.FORMAT_KEY); + model.setValue(RoomObjectVariable.FURNITURE_CRACKABLE_STATE, this._state); + model.setValue(RoomObjectVariable.FURNITURE_CRACKABLE_HITS, this._hits); + model.setValue(RoomObjectVariable.FURNITURE_CRACKABLE_TARGET, this._target); + } + + public getLegacyString(): string + { + return this._state; + } + + public compare(data: IObjectData): boolean + { + return true; + } + + public get hits(): number + { + return this._hits; + } + + public get target(): number + { + return this._target; + } +} \ No newline at end of file diff --git a/src/nitro/room/object/data/type/EmptyDataType.ts b/src/nitro/room/object/data/type/EmptyDataType.ts new file mode 100644 index 00000000..905a7c4d --- /dev/null +++ b/src/nitro/room/object/data/type/EmptyDataType.ts @@ -0,0 +1,39 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IRoomObjectModel } from '../../../../../room/object/IRoomObjectModel'; +import { RoomObjectVariable } from '../../RoomObjectVariable'; +import { IObjectData } from '../IObjectData'; +import { ObjectDataBase } from '../ObjectDataBase'; +import { ObjectDataKey } from '../ObjectDataKey'; + +export class EmptyDataType extends ObjectDataBase implements IObjectData +{ + public static FORMAT_KEY = ObjectDataKey.EMPTY_KEY; + + private _state: string; + + public parseWrapper(wrapper: IMessageDataWrapper): void + { + if(!wrapper) return; + + this._state = ''; + + super.parseWrapper(wrapper); + } + + public writeRoomObjectModel(model: IRoomObjectModel): void + { + super.writeRoomObjectModel(model); + + model.setValue(RoomObjectVariable.FURNITURE_DATA_FORMAT, EmptyDataType.FORMAT_KEY); + } + + public getLegacyString(): string + { + return this._state; + } + + public compare(data: IObjectData): boolean + { + return super.compare(data); + } +} \ No newline at end of file diff --git a/src/nitro/room/object/data/type/HighScoreData.ts b/src/nitro/room/object/data/type/HighScoreData.ts new file mode 100644 index 00000000..cb18b33f --- /dev/null +++ b/src/nitro/room/object/data/type/HighScoreData.ts @@ -0,0 +1,36 @@ +export class HighScoreData +{ + private _score: number; + private _users: string[]; + + constructor() + { + this._score = -1; + this._users = []; + } + + public get score(): number + { + return this._score; + } + + public set score(k: number) + { + this._score = k; + } + + public get users(): string[] + { + return this._users; + } + + public set users(k: string[]) + { + this._users = k; + } + + public addUsername(k: string): void + { + this._users.push(k); + } +} \ No newline at end of file diff --git a/src/nitro/room/object/data/type/HighScoreDataType.ts b/src/nitro/room/object/data/type/HighScoreDataType.ts new file mode 100644 index 00000000..1278175b --- /dev/null +++ b/src/nitro/room/object/data/type/HighScoreDataType.ts @@ -0,0 +1,121 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IRoomObjectModel } from '../../../../../room/object/IRoomObjectModel'; +import { RoomObjectVariable } from '../../RoomObjectVariable'; +import { IObjectData } from '../IObjectData'; +import { ObjectDataBase } from '../ObjectDataBase'; +import { ObjectDataKey } from '../ObjectDataKey'; +import { HighScoreData } from './HighScoreData'; + +export class HighScoreDataType extends ObjectDataBase implements IObjectData +{ + public static FORMAT_KEY = ObjectDataKey.HIGHSCORE_KEY; + + private _state: string; + private _scoreType: number; + private _clearType: number; + private _entries: HighScoreData[]; + + constructor() + { + super(); + + this._state = ''; + this._scoreType = -1; + this._clearType = -1; + this._entries = []; + } + + public parseWrapper(wrapper: IMessageDataWrapper): void + { + if(!wrapper) return; + + this._state = wrapper.readString(); + this._scoreType = wrapper.readInt(); + this._clearType = wrapper.readInt(); + + let totalScores = wrapper.readInt(); + + while(totalScores > 0) + { + const data = new HighScoreData(); + + data.score = wrapper.readInt(); + + let totalUsers = wrapper.readInt(); + + while(totalUsers > 0) + { + data.addUsername(wrapper.readString()); + + totalUsers--; + } + + this._entries.push(data); + + totalScores--; + } + + super.parseWrapper(wrapper); + } + + public initializeFromRoomObjectModel(model: IRoomObjectModel): void + { + this._scoreType = model.getValue(RoomObjectVariable.FURNITURE_HIGHSCORE_SCORE_TYPE); + this._clearType = model.getValue(RoomObjectVariable.FURNITURE_HIGHSCORE_CLEAR_TYPE); + this._entries = []; + + const totalEntries = model.getValue(RoomObjectVariable.FURNITURE_HIGHSCORE_DATA_ENTRY_COUNT); + + let i = 0; + + while(i < totalEntries) + { + const data = new HighScoreData(); + + data.score = model.getValue(RoomObjectVariable.FURNITURE_HIGHSCORE_DATA_ENTRY_BASE_SCORE_ + i); + data.users = model.getValue(RoomObjectVariable.FURNITURE_HIGHSCORE_DATA_ENTRY_BASE_USERS_ + i); + + this._entries.push(data); + + i++; + } + + super.initializeFromRoomObjectModel(model); + } + + public writeRoomObjectModel(model: IRoomObjectModel): void + { + super.writeRoomObjectModel(model); + + model.setValue(RoomObjectVariable.FURNITURE_DATA_FORMAT, HighScoreDataType.FORMAT_KEY); + model.setValue(RoomObjectVariable.FURNITURE_HIGHSCORE_SCORE_TYPE, this._scoreType); + model.setValue(RoomObjectVariable.FURNITURE_HIGHSCORE_CLEAR_TYPE, this._clearType); + + if(this._entries) + { + model.setValue(RoomObjectVariable.FURNITURE_HIGHSCORE_DATA_ENTRY_COUNT, this._entries.length); + + let i = 0; + + while(i < this._entries.length) + { + const entry = this._entries[i]; + + model.setValue((RoomObjectVariable.FURNITURE_HIGHSCORE_DATA_ENTRY_BASE_SCORE_ + i), entry.score); + model.setValue((RoomObjectVariable.FURNITURE_HIGHSCORE_DATA_ENTRY_BASE_USERS_ + i), entry.users); + + i++; + } + } + } + + public getLegacyString(): string + { + return this._state; + } + + public get entries(): HighScoreData[] + { + return this._entries; + } +} \ No newline at end of file diff --git a/src/nitro/room/object/data/type/LegacyDataType.ts b/src/nitro/room/object/data/type/LegacyDataType.ts new file mode 100644 index 00000000..c2c66951 --- /dev/null +++ b/src/nitro/room/object/data/type/LegacyDataType.ts @@ -0,0 +1,59 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IRoomObjectModel } from '../../../../../room/object/IRoomObjectModel'; +import { RoomObjectVariable } from '../../RoomObjectVariable'; +import { IObjectData } from '../IObjectData'; +import { ObjectDataBase } from '../ObjectDataBase'; +import { ObjectDataKey } from '../ObjectDataKey'; + +export class LegacyDataType extends ObjectDataBase implements IObjectData +{ + public static FORMAT_KEY = ObjectDataKey.LEGACY_KEY; + + private _data: string; + + constructor() + { + super(); + + this._data = ''; + } + + public parseWrapper(wrapper: IMessageDataWrapper): void + { + if(!wrapper) return; + + this._data = wrapper.readString(); + + super.parseWrapper(wrapper); + } + + public initializeFromRoomObjectModel(model: IRoomObjectModel): void + { + super.initializeFromRoomObjectModel(model); + + this._data = model.getValue(RoomObjectVariable.FURNITURE_DATA); + } + + public writeRoomObjectModel(model: IRoomObjectModel): void + { + super.writeRoomObjectModel(model); + + model.setValue(RoomObjectVariable.FURNITURE_DATA_FORMAT, LegacyDataType.FORMAT_KEY); + model.setValue(RoomObjectVariable.FURNITURE_DATA, this._data); + } + + public getLegacyString(): string + { + return this._data; + } + + public compare(data: IObjectData): boolean + { + return (this._data === data.getLegacyString()); + } + + public setString(data: string): void + { + this._data = data; + } +} \ No newline at end of file diff --git a/src/nitro/room/object/data/type/MapDataType.ts b/src/nitro/room/object/data/type/MapDataType.ts new file mode 100644 index 00000000..824f46f1 --- /dev/null +++ b/src/nitro/room/object/data/type/MapDataType.ts @@ -0,0 +1,79 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IRoomObjectModel } from '../../../../../room/object/IRoomObjectModel'; +import { RoomObjectVariable } from '../../RoomObjectVariable'; +import { IObjectData } from '../IObjectData'; +import { ObjectDataBase } from '../ObjectDataBase'; +import { ObjectDataKey } from '../ObjectDataKey'; + +export class MapDataType extends ObjectDataBase +{ + public static FORMAT_KEY = ObjectDataKey.MAP_KEY; + + private static STATE: string = 'state'; + private static RARITY: string = 'rarity'; + + private _data: { [index: string]: string }; + + constructor() + { + super(); + + this._data = {}; + } + + public parseWrapper(wrapper: IMessageDataWrapper): void + { + if(!wrapper) return; + + this._data = {}; + + const totalSets = wrapper.readInt(); + + if(totalSets) for(let i = 0; i < totalSets; i++) this._data[wrapper.readString()] = wrapper.readString(); + + super.parseWrapper(wrapper); + } + + public initializeFromRoomObjectModel(model: IRoomObjectModel): void + { + super.initializeFromRoomObjectModel(model); + + this._data = model.getValue<{ [index: string]: string }>(RoomObjectVariable.FURNITURE_DATA) || {}; + } + + public writeRoomObjectModel(model: IRoomObjectModel): void + { + super.writeRoomObjectModel(model); + + model.setValue(RoomObjectVariable.FURNITURE_DATA_FORMAT, MapDataType.FORMAT_KEY); + model.setValue(RoomObjectVariable.FURNITURE_DATA, this._data); + } + + public getLegacyString(): string + { + if(!this._data || !this._data.length) return ''; + + const state = this._data[MapDataType.STATE]; + + if(state === undefined || state === null) return ''; + + return state; + } + + public compare(data: IObjectData): boolean + { + return false; + } + + public getValue(key: string): string + { + return this._data[key]; + } + + // TODO: How to get the keys? + public get data() + { + return this._data; + } + +} diff --git a/src/nitro/room/object/data/type/NumberDataType.ts b/src/nitro/room/object/data/type/NumberDataType.ts new file mode 100644 index 00000000..d7a806e1 --- /dev/null +++ b/src/nitro/room/object/data/type/NumberDataType.ts @@ -0,0 +1,91 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IRoomObjectModel } from '../../../../../room/object/IRoomObjectModel'; +import { RoomObjectVariable } from '../../RoomObjectVariable'; +import { IObjectData } from '../IObjectData'; +import { ObjectDataBase } from '../ObjectDataBase'; +import { ObjectDataKey } from '../ObjectDataKey'; + +export class NumberDataType extends ObjectDataBase +{ + public static FORMAT_KEY = ObjectDataKey.NUMBER_KEY; + + private static STATE: number = 0; + + private _data: number[]; + + constructor() + { + super(); + + this._data = []; + } + + public parseWrapper(wrapper: IMessageDataWrapper): void + { + if(!wrapper) return; + + this._data = []; + + const totalNumbers = wrapper.readInt(); + + if(totalNumbers) for(let i = 0; i < totalNumbers; i++) this._data.push(wrapper.readInt()); + + super.parseWrapper(wrapper); + } + + public initializeFromRoomObjectModel(model: IRoomObjectModel): void + { + super.initializeFromRoomObjectModel(model); + + this._data = model.getValue(RoomObjectVariable.FURNITURE_DATA); + } + + public writeRoomObjectModel(model: IRoomObjectModel): void + { + super.writeRoomObjectModel(model); + + model.setValue(RoomObjectVariable.FURNITURE_DATA_FORMAT, NumberDataType.FORMAT_KEY); + model.setValue(RoomObjectVariable.FURNITURE_DATA, this._data); + } + + public getLegacyString(): string + { + if(!this._data || !this._data.length) return ''; + + return this._data[NumberDataType.STATE].toString(); + } + + public compare(data: IObjectData): boolean + { + if(!(data instanceof NumberDataType)) return false; + + let i = 0; + + while(i < this._data.length) + { + if(i === 0) + { + // + } + else + { + if(this._data[i] !== data.getValue(i)) return false; + } + + i++; + } + + return true; + } + + public getValue(index: number): number + { + if(!this._data || !this._data.length) return -1; + + const value = this._data[index]; + + if(value === undefined || value === null) return -1; + + return value; + } +} \ No newline at end of file diff --git a/src/nitro/room/object/data/type/StringDataType.ts b/src/nitro/room/object/data/type/StringDataType.ts new file mode 100644 index 00000000..f63dd3d8 --- /dev/null +++ b/src/nitro/room/object/data/type/StringDataType.ts @@ -0,0 +1,90 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IRoomObjectModel } from '../../../../../room/object/IRoomObjectModel'; +import { RoomObjectVariable } from '../../RoomObjectVariable'; +import { IObjectData } from '../IObjectData'; +import { ObjectDataBase } from '../ObjectDataBase'; +import { ObjectDataKey } from '../ObjectDataKey'; + +export class StringDataType extends ObjectDataBase +{ + public static FORMAT_KEY = ObjectDataKey.STRING_KEY; + + private static STATE: number = 0; + + private _data: string[]; + + constructor() + { + super(); + + this._data = []; + } + + public parseWrapper(wrapper: IMessageDataWrapper): void + { + if(!wrapper) return; + + this._data = []; + + const totalStrings = wrapper.readInt(); + + if(totalStrings) for(let i = 0; i < totalStrings; i++) this._data.push(wrapper.readString()); + + super.parseWrapper(wrapper); + } + + public initializeFromRoomObjectModel(model: IRoomObjectModel): void + { + super.initializeFromRoomObjectModel(model); + + this._data = model.getValue(RoomObjectVariable.FURNITURE_DATA); + } + + public writeRoomObjectModel(model: IRoomObjectModel): void + { + super.writeRoomObjectModel(model); + + model.setValue(RoomObjectVariable.FURNITURE_DATA_FORMAT, StringDataType.FORMAT_KEY); + model.setValue(RoomObjectVariable.FURNITURE_DATA, this._data); + } + + public getLegacyString(): string + { + if(!this._data || !this._data.length) return ''; + + return this._data[StringDataType.STATE]; + } + + public compare(data: IObjectData): boolean + { + if(!(data instanceof StringDataType)) return false; + + let i = 0; + + while(i < this._data.length) + { + if(i === 0) + { + // + } + else + { + if(this._data[i] !== data.getValue(i)) return false; + } + + i++; + } + + return true; + } + + public getValue(index: number): string + { + return this._data[index] || ''; + } + + public setValue(data: string[]): void + { + this._data = data; + } +} diff --git a/src/nitro/room/object/data/type/VoteDataType.ts b/src/nitro/room/object/data/type/VoteDataType.ts new file mode 100644 index 00000000..ff362924 --- /dev/null +++ b/src/nitro/room/object/data/type/VoteDataType.ts @@ -0,0 +1,66 @@ +import { IMessageDataWrapper } from '../../../../../core/communication/messages/IMessageDataWrapper'; +import { IRoomObjectModel } from '../../../../../room/object/IRoomObjectModel'; +import { RoomObjectVariable } from '../../RoomObjectVariable'; +import { IObjectData } from '../IObjectData'; +import { ObjectDataBase } from '../ObjectDataBase'; +import { ObjectDataKey } from '../ObjectDataKey'; + +export class VoteDataType extends ObjectDataBase +{ + public static FORMAT_KEY = ObjectDataKey.VOTE_KEY; + + private _state: string; + private _result: number; + + constructor() + { + super(); + + this._state = ''; + this._result = 0; + } + + public parseWrapper(wrapper: IMessageDataWrapper): void + { + if(!wrapper) return; + + this._state = wrapper.readString(); + this._result = wrapper.readInt(); + + super.parseWrapper(wrapper); + } + + public writeRoomObjectModel(model: IRoomObjectModel): void + { + super.writeRoomObjectModel(model); + + model.setValue(RoomObjectVariable.FURNITURE_DATA_FORMAT, VoteDataType.FORMAT_KEY); + + const data: { [index: string]: string } = {}; + + data['S'] = this._state; + data['R'] = this._result.toString(); + + model.setValue(RoomObjectVariable.FURNITURE_DATA, data); + } + + public getLegacyString(): string + { + return this._state; + } + + public compare(data: IObjectData): boolean + { + return true; + } + + public setString(state: string): void + { + this._state = state; + } + + public get result(): number + { + return this._result; + } +} \ No newline at end of file diff --git a/src/nitro/room/object/logic/MovingObjectLogic.ts b/src/nitro/room/object/logic/MovingObjectLogic.ts new file mode 100644 index 00000000..4c0d7264 --- /dev/null +++ b/src/nitro/room/object/logic/MovingObjectLogic.ts @@ -0,0 +1,143 @@ +import { RoomObjectUpdateMessage } from '../../../../room/messages/RoomObjectUpdateMessage'; +import { IRoomObjectController } from '../../../../room/object/IRoomObjectController'; +import { RoomObjectLogicBase } from '../../../../room/object/logic/RoomObjectLogicBase'; +import { IVector3D } from '../../../../room/utils/IVector3D'; +import { Vector3d } from '../../../../room/utils/Vector3d'; +import { ObjectMoveUpdateMessage } from '../../messages/ObjectMoveUpdateMessage'; +import { RoomObjectVariable } from '../RoomObjectVariable'; + +export class MovingObjectLogic extends RoomObjectLogicBase +{ + private static TEMP_VECTOR: Vector3d = new Vector3d(); + + private _liftAmount: number; + + private _location: Vector3d; + private _locationDelta: Vector3d; + private _lastUpdateTime: number; + private _changeTime: number; + private _updateInterval: number; + + constructor() + { + super(); + + this._liftAmount = 0; + + this._location = new Vector3d(); + this._locationDelta = new Vector3d(); + this._lastUpdateTime = 0; + this._changeTime = 0; + this._updateInterval = 500; + } + + public dispose(): void + { + this._liftAmount = 0; + + super.dispose(); + } + + public update(time: number): void + { + super.update(time); + + const locationOffset = this.getLocationOffset(); + const model = this.object && this.object.model; + + if(model) + { + if(locationOffset) + { + if(this._liftAmount !== locationOffset.z) + { + this._liftAmount = locationOffset.z; + + model.setValue(RoomObjectVariable.FURNITURE_LIFT_AMOUNT, this._liftAmount); + } + } + else + { + if(this._liftAmount !== 0) + { + this._liftAmount = 0; + + model.setValue(RoomObjectVariable.FURNITURE_LIFT_AMOUNT, this._liftAmount); + } + } + } + + if((this._locationDelta.length > 0) || locationOffset) + { + const vector = MovingObjectLogic.TEMP_VECTOR; + + let difference = (this.time - this._changeTime); + + if(difference === (this._updateInterval >> 1)) difference++; + + if(difference > this._updateInterval) difference = this._updateInterval; + + if(this._locationDelta.length > 0) + { + vector.assign(this._locationDelta); + vector.multiply((difference / this._updateInterval)); + vector.add(this._location); + } + else + { + vector.assign(this._location); + } + + if(locationOffset) vector.add(locationOffset); + + this.object.setLocation(vector); + + if(difference === this._updateInterval) + { + this._locationDelta.x = 0; + this._locationDelta.y = 0; + this._locationDelta.z = 0; + } + } + + this._lastUpdateTime = this.time; + } + + public setObject(object: IRoomObjectController): void + { + super.setObject(object); + + if(object) this._location.assign(object.getLocation()); + } + + public processUpdateMessage(message: RoomObjectUpdateMessage): void + { + if(!message) return; + + super.processUpdateMessage(message); + + if(message.location) this._location.assign(message.location); + + if(message instanceof ObjectMoveUpdateMessage) return this.processMoveMessage(message); + } + + private processMoveMessage(message: ObjectMoveUpdateMessage): void + { + if(!message || !this.object || !message.location) return; + + this._changeTime = this._lastUpdateTime; + + this._locationDelta.assign(message.targetLocation); + this._locationDelta.subtract(this._location); + } + + protected getLocationOffset(): IVector3D + { + return null; + } + + protected get lastUpdateTime(): number + { + return this._lastUpdateTime; + } +} \ No newline at end of file diff --git a/src/nitro/room/object/logic/avatar/AvatarLogic.ts b/src/nitro/room/object/logic/avatar/AvatarLogic.ts new file mode 100644 index 00000000..1ac68b28 --- /dev/null +++ b/src/nitro/room/object/logic/avatar/AvatarLogic.ts @@ -0,0 +1,528 @@ + +import { RoomObjectMouseEvent } from '../../../../../room/events/RoomObjectMouseEvent'; +import { RoomSpriteMouseEvent } from '../../../../../room/events/RoomSpriteMouseEvent'; +import { RoomObjectUpdateMessage } from '../../../../../room/messages/RoomObjectUpdateMessage'; +import { IRoomObjectModel } from '../../../../../room/object/IRoomObjectModel'; +import { IRoomGeometry } from '../../../../../room/utils/IRoomGeometry'; +import { Vector3d } from '../../../../../room/utils/Vector3d'; +import { AvatarAction } from '../../../../avatar/enum/AvatarAction'; +import { Nitro } from '../../../../Nitro'; +import { MouseEventType } from '../../../../ui/MouseEventType'; +import { RoomObjectFurnitureActionEvent } from '../../../events/RoomObjectFurnitureActionEvent'; +import { RoomObjectMoveEvent } from '../../../events/RoomObjectMoveEvent'; +import { ObjectAvatarCarryObjectUpdateMessage } from '../../../messages/ObjectAvatarCarryObjectUpdateMessage'; +import { ObjectAvatarChatUpdateMessage } from '../../../messages/ObjectAvatarChatUpdateMessage'; +import { ObjectAvatarDanceUpdateMessage } from '../../../messages/ObjectAvatarDanceUpdateMessage'; +import { ObjectAvatarEffectUpdateMessage } from '../../../messages/ObjectAvatarEffectUpdateMessage'; +import { ObjectAvatarExpressionUpdateMessage } from '../../../messages/ObjectAvatarExpressionUpdateMessage'; +import { ObjectAvatarFigureUpdateMessage } from '../../../messages/ObjectAvatarFigureUpdateMessage'; +import { ObjectAvatarFlatControlUpdateMessage } from '../../../messages/ObjectAvatarFlatControlUpdateMessage'; +import { ObjectAvatarGestureUpdateMessage } from '../../../messages/ObjectAvatarGestureUpdateMessage'; +import { ObjectAvatarMutedUpdateMessage } from '../../../messages/ObjectAvatarMutedUpdateMessage'; +import { ObjectAvatarOwnMessage } from '../../../messages/ObjectAvatarOwnMessage'; +import { ObjectAvatarPlayerValueUpdateMessage } from '../../../messages/ObjectAvatarPlayerValueUpdateMessage'; +import { ObjectAvatarPlayingGameUpdateMessage } from '../../../messages/ObjectAvatarPlayingGameUpdateMessage'; +import { ObjectAvatarPostureUpdateMessage } from '../../../messages/ObjectAvatarPostureUpdateMessage'; +import { ObjectAvatarSelectedMessage } from '../../../messages/ObjectAvatarSelectedMessage'; +import { ObjectAvatarSignUpdateMessage } from '../../../messages/ObjectAvatarSignUpdateMessage'; +import { ObjectAvatarSleepUpdateMessage } from '../../../messages/ObjectAvatarSleepUpdateMessage'; +import { ObjectAvatarTypingUpdateMessage } from '../../../messages/ObjectAvatarTypingUpdateMessage'; +import { ObjectAvatarUpdateMessage } from '../../../messages/ObjectAvatarUpdateMessage'; +import { ObjectAvatarUseObjectUpdateMessage } from '../../../messages/ObjectAvatarUseObjectUpdateMessage'; +import { RoomObjectVariable } from '../../RoomObjectVariable'; +import { MovingObjectLogic } from '../MovingObjectLogic'; + +export class AvatarLogic extends MovingObjectLogic +{ + private static MAX_HAND_ID: number = 999999999; + private static MAX_HAND_USE_ID: number = 999; + private static _Str_13364: number = 28; + private static _Str_8860: number = 500; + private static _Str_15351: number = 29; + private static _Str_13733: number = 184; + private static _Str_13094: number = 185; + + private _selected: boolean; + private _reportedLocation: Vector3d; + private _effectChangeTimeStamp: number; + private _newEffect: number; + private _blinkingStartTimestamp: number; + private _blinkingEndTimestamp: number; + private _talkingEndTimestamp: number; + private _talkingPauseStartTimestamp: number; + private _talkingPauseEndTimestamp: number; + private _carryObjectStartTimestamp: number; + private _carryObjectEndTimestamp: number; + private _allowUseCarryObject: boolean; + private _animationEndTimestamp: number; + private _signEndTimestamp: number; + private _gestureEndTimestamp: number; + private _numberValueEndTimestamp: number; + + constructor() + { + super(); + + this._selected = false; + this._reportedLocation = null; + this._effectChangeTimeStamp = 0; + this._newEffect = 0; + this._blinkingStartTimestamp = Nitro.instance.time + this.randomBlinkStartTimestamp(); + this._blinkingEndTimestamp = 0; + this._talkingEndTimestamp = 0; + this._talkingPauseStartTimestamp = 0; + this._talkingPauseEndTimestamp = 0; + this._carryObjectStartTimestamp = 0; + this._carryObjectEndTimestamp = 0; + this._allowUseCarryObject = false; + this._animationEndTimestamp = 0; + this._signEndTimestamp = 0; + this._gestureEndTimestamp = 0; + this._numberValueEndTimestamp = 0; + } + + public getEventTypes(): string[] + { + const types = [ RoomObjectMouseEvent.CLICK, RoomObjectMoveEvent.POSITION_CHANGED, RoomObjectMouseEvent.MOUSE_ENTER, RoomObjectMouseEvent.MOUSE_LEAVE, RoomObjectFurnitureActionEvent.MOUSE_BUTTON, RoomObjectFurnitureActionEvent.MOUSE_ARROW ]; + + return this.mergeTypes(super.getEventTypes(), types); + } + + public dispose(): void + { + if(this._selected && this.object) + { + if(this.eventDispatcher) this.eventDispatcher.dispatchEvent(new RoomObjectMoveEvent(RoomObjectMoveEvent.OBJECT_REMOVED, this.object)); + } + + super.dispose(); + + this._reportedLocation = null; + } + + public update(time: number): void + { + super.update(time); + + if(this._selected && this.object) + { + if(this.eventDispatcher) + { + const location = this.object.getLocation(); + + if(((!this._reportedLocation || (this._reportedLocation.x !== location.x)) || (this._reportedLocation.y !== location.y)) || (this._reportedLocation.z !== location.z)) + { + if(!this._reportedLocation) this._reportedLocation = new Vector3d(); + + this._reportedLocation.assign(location); + + this.eventDispatcher.dispatchEvent(new RoomObjectMoveEvent(RoomObjectMoveEvent.POSITION_CHANGED, this.object)); + } + } + } + + const model = this.object && this.object.model; + + if(model) this.updateModel(this.time, model); + } + + private updateModel(time: number, model: IRoomObjectModel): void + { + if(this._talkingEndTimestamp > 0) + { + if(time > this._talkingEndTimestamp) + { + model.setValue(RoomObjectVariable.FIGURE_TALK, 0); + + this._talkingEndTimestamp = 0; + this._talkingPauseStartTimestamp = 0; + this._talkingPauseEndTimestamp = 0; + } + else + { + if(!this._talkingPauseEndTimestamp && !this._talkingPauseStartTimestamp) + { + this._talkingPauseStartTimestamp = time + this.randomTalkingPauseStartTimestamp(); + this._talkingPauseEndTimestamp = this._talkingPauseStartTimestamp + this.randomTalkingPauseEndTimestamp(); + } + else + { + if((this._talkingPauseStartTimestamp > 0) && (time > this._talkingPauseStartTimestamp)) + { + model.setValue(RoomObjectVariable.FIGURE_TALK, 0); + + this._talkingPauseStartTimestamp = 0; + } + else + { + if((this._talkingPauseEndTimestamp > 0) && (time > this._talkingPauseEndTimestamp)) + { + model.setValue(RoomObjectVariable.FIGURE_TALK, 1); + + this._talkingPauseEndTimestamp = 0; + } + } + } + } + } + + if((this._animationEndTimestamp > 0) && (time > this._animationEndTimestamp)) + { + model.setValue(RoomObjectVariable.FIGURE_EXPRESSION, 0); + + this._animationEndTimestamp = 0; + } + + if((this._gestureEndTimestamp > 0) && (time > this._gestureEndTimestamp)) + { + model.setValue(RoomObjectVariable.FIGURE_GESTURE, 0); + + this._gestureEndTimestamp = 0; + } + + if((this._signEndTimestamp > 0) && (time > this._signEndTimestamp)) + { + model.setValue(RoomObjectVariable.FIGURE_SIGN, -1); + + this._signEndTimestamp = 0; + } + + if(this._carryObjectEndTimestamp > 0) + { + if(time > this._carryObjectEndTimestamp) + { + model.setValue(RoomObjectVariable.FIGURE_CARRY_OBJECT, 0); + model.setValue(RoomObjectVariable.FIGURE_USE_OBJECT, 0); + + this._carryObjectStartTimestamp = 0; + this._carryObjectEndTimestamp = 0; + this._allowUseCarryObject = false; + } + } + + if(this._allowUseCarryObject) + { + if((time - this._carryObjectStartTimestamp) > 5000) + { + if(((time - this._carryObjectStartTimestamp) % 10000) < 1000) + { + model.setValue(RoomObjectVariable.FIGURE_USE_OBJECT, 1); + } + else + { + model.setValue(RoomObjectVariable.FIGURE_USE_OBJECT, 0); + } + } + } + + if((this._blinkingStartTimestamp > -1) && (time > this._blinkingStartTimestamp)) + { + model.setValue(RoomObjectVariable.FIGURE_BLINK, 1); + + this._blinkingStartTimestamp = time + this.randomBlinkStartTimestamp(); + this._blinkingEndTimestamp = time + this.randomBlinkEndTimestamp(); + } + + if((this._blinkingEndTimestamp > 0) && (time > this._blinkingEndTimestamp)) + { + model.setValue(RoomObjectVariable.FIGURE_BLINK, 0); + + this._blinkingEndTimestamp = 0; + } + + if((this._effectChangeTimeStamp > 0) && (time > this._effectChangeTimeStamp)) + { + model.setValue(RoomObjectVariable.FIGURE_EFFECT, this._newEffect); + + this._effectChangeTimeStamp = 0; + } + + if((this._numberValueEndTimestamp > 0) && (time > this._numberValueEndTimestamp)) + { + model.setValue(RoomObjectVariable.FIGURE_NUMBER_VALUE, 0); + + this._numberValueEndTimestamp = 0; + } + } + + public processUpdateMessage(message: RoomObjectUpdateMessage): void + { + if(!message || !this.object) return; + + super.processUpdateMessage(message); + + const model = this.object && this.object.model; + + if(!model) return; + + if(message instanceof ObjectAvatarPostureUpdateMessage) + { + model.setValue(RoomObjectVariable.FIGURE_POSTURE, message.postureType); + model.setValue(RoomObjectVariable.FIGURE_POSTURE_PARAMETER, message.parameter); + + return; + } + + if(message instanceof ObjectAvatarChatUpdateMessage) + { + model.setValue(RoomObjectVariable.FIGURE_TALK, 1); + + this._talkingEndTimestamp = (this.time + (message.numberOfWords * 1000)); + + return; + } + + if(message instanceof ObjectAvatarTypingUpdateMessage) + { + model.setValue(RoomObjectVariable.FIGURE_IS_TYPING, message.isTyping ? 1 : 0); + + return; + } + + if(message instanceof ObjectAvatarMutedUpdateMessage) + { + model.setValue(RoomObjectVariable.FIGURE_IS_MUTED, (message.isMuted ? 1 : 0)); + + return; + } + + if(message instanceof ObjectAvatarPlayingGameUpdateMessage) + { + model.setValue(RoomObjectVariable.FIGURE_IS_PLAYING_GAME, (message.isPlayingGame ? 1 : 0)); + + return; + } + + if(message instanceof ObjectAvatarUpdateMessage) + { + model.setValue(RoomObjectVariable.HEAD_DIRECTION, message.headDirection); + model.setValue(RoomObjectVariable.FIGURE_CAN_STAND_UP, message.canStandUp); + model.setValue(RoomObjectVariable.FIGURE_VERTICAL_OFFSET, message.baseY); + + return; + } + + if(message instanceof ObjectAvatarGestureUpdateMessage) + { + model.setValue(RoomObjectVariable.FIGURE_GESTURE, message.gesture); + + this._gestureEndTimestamp = (this.time + 3000); + + return; + } + + if(message instanceof ObjectAvatarExpressionUpdateMessage) + { + model.setValue(RoomObjectVariable.FIGURE_EXPRESSION, message.expressionType); + + this._animationEndTimestamp = AvatarAction.getExpressionTimeout(model.getValue(RoomObjectVariable.FIGURE_EXPRESSION)); + + if(this._animationEndTimestamp > -1) this._animationEndTimestamp += this.time; + + return; + } + + if(message instanceof ObjectAvatarDanceUpdateMessage) + { + model.setValue(RoomObjectVariable.FIGURE_DANCE, message.danceStyle); + + return; + } + + if(message instanceof ObjectAvatarSleepUpdateMessage) + { + model.setValue(RoomObjectVariable.FIGURE_SLEEP, message.isSleeping ? 1 : 0); + + if(message.isSleeping) this._blinkingStartTimestamp = -1; + else this._blinkingStartTimestamp = (this.time + this.randomBlinkStartTimestamp()); + + return; + } + + if(message instanceof ObjectAvatarPlayerValueUpdateMessage) + { + model.setValue(RoomObjectVariable.FIGURE_NUMBER_VALUE, message.value); + + this._numberValueEndTimestamp = (this.time + 3000); + + return; + } + + if(message instanceof ObjectAvatarEffectUpdateMessage) + { + this.updateAvatarEffect(message.effect, message.delayMilliseconds, model); + + return; + } + + if(message instanceof ObjectAvatarCarryObjectUpdateMessage) + { + model.setValue(RoomObjectVariable.FIGURE_CARRY_OBJECT, message.itemType); + model.setValue(RoomObjectVariable.FIGURE_USE_OBJECT, 0); + + if(message.itemType === 0) + { + this._carryObjectStartTimestamp = 0; + this._carryObjectEndTimestamp = 0; + this._allowUseCarryObject = false; + } + else + { + this._carryObjectStartTimestamp = this.time; + + if(message.itemType < AvatarLogic.MAX_HAND_ID) + { + this._carryObjectEndTimestamp = 0; + this._allowUseCarryObject = message.itemType <= AvatarLogic.MAX_HAND_USE_ID; + } + else + { + this._carryObjectEndTimestamp = this._carryObjectStartTimestamp + 1500; + this._allowUseCarryObject = false; + } + } + + return; + } + + if(message instanceof ObjectAvatarUseObjectUpdateMessage) + { + model.setValue(RoomObjectVariable.FIGURE_USE_OBJECT, message.itemType); + + return; + } + + if(message instanceof ObjectAvatarSignUpdateMessage) + { + model.setValue(RoomObjectVariable.FIGURE_SIGN, message.signType); + + this._signEndTimestamp = (this.time + 5000); + + return; + } + + if(message instanceof ObjectAvatarFlatControlUpdateMessage) + { + model.setValue(RoomObjectVariable.FIGURE_FLAT_CONTROL, message.level); + + return; + } + + if(message instanceof ObjectAvatarFigureUpdateMessage) + { + model.setValue(RoomObjectVariable.FIGURE, message.figure); + model.setValue(RoomObjectVariable.GENDER, message.gender); + + return; + } + + if(message instanceof ObjectAvatarSelectedMessage) + { + this._selected = message.selected; + this._reportedLocation = null; + + return; + } + + if(message instanceof ObjectAvatarOwnMessage) + { + model.setValue(RoomObjectVariable.OWN_USER, 1); + + return; + } + } + + private updateAvatarEffect(effect: number, delay: number, model: IRoomObjectModel): void + { + if(effect === AvatarLogic._Str_13364) + { + this._effectChangeTimeStamp = (Nitro.instance.time + AvatarLogic._Str_8860); + this._newEffect = AvatarLogic._Str_15351; + } + + else if(effect === AvatarLogic._Str_13733) + { + this._effectChangeTimeStamp = (Nitro.instance.time + AvatarLogic._Str_8860); + this._newEffect = AvatarLogic._Str_13094; + } + + else if(model.getValue(RoomObjectVariable.FIGURE_EFFECT) === AvatarLogic._Str_15351) + { + this._effectChangeTimeStamp = (Nitro.instance.time + AvatarLogic._Str_8860); + this._newEffect = effect; + + effect = AvatarLogic._Str_13364; + } + + else if(model.getValue(RoomObjectVariable.FIGURE_EFFECT) === AvatarLogic._Str_13094) + { + this._effectChangeTimeStamp = (Nitro.instance.time + AvatarLogic._Str_8860); + this._newEffect = effect; + + effect = AvatarLogic._Str_13733; + } + + else if(delay === 0) + { + this._effectChangeTimeStamp = 0; + } + + else + { + this._effectChangeTimeStamp = (Nitro.instance.time + delay); + this._newEffect = effect; + + return; + } + + model.setValue(RoomObjectVariable.FIGURE_EFFECT, effect); + } + + public mouseEvent(event: RoomSpriteMouseEvent, geometry: IRoomGeometry): void + { + let eventType: string = null; + + switch(event.type) + { + case MouseEventType.MOUSE_CLICK: + eventType = RoomObjectMouseEvent.CLICK; + break; + case MouseEventType.ROLL_OVER: + eventType = RoomObjectMouseEvent.MOUSE_ENTER; + + if(this.object.model) this.object.model.setValue(RoomObjectVariable.FIGURE_HIGHLIGHT, 1); + + if(this.eventDispatcher) this.eventDispatcher.dispatchEvent(new RoomObjectFurnitureActionEvent(RoomObjectFurnitureActionEvent.MOUSE_BUTTON, this.object)); + break; + case MouseEventType.ROLL_OUT: + eventType = RoomObjectMouseEvent.MOUSE_LEAVE; + + if(this.object.model) this.object.model.setValue(RoomObjectVariable.FIGURE_HIGHLIGHT, 0); + + if(this.eventDispatcher) this.eventDispatcher.dispatchEvent(new RoomObjectFurnitureActionEvent(RoomObjectFurnitureActionEvent.MOUSE_ARROW, this.object)); + break; + } + + if(eventType && this.eventDispatcher) this.eventDispatcher.dispatchEvent(new RoomObjectMouseEvent(eventType, this.object, event._Str_3463, event.altKey, event.ctrlKey, event.shiftKey, event.buttonDown)); + } + + private randomTalkingPauseStartTimestamp(): number + { + return 100 + (Math.random() * 200); + } + + private randomTalkingPauseEndTimestamp(): number + { + return 75 + (Math.random() * 75); + } + + private randomBlinkStartTimestamp(): number + { + return 4500 + (Math.random() * 1000); + } + + private randomBlinkEndTimestamp(): number + { + return 50 + (Math.random() * 200); + } +} diff --git a/src/nitro/room/object/logic/furniture/FurnitureBadgeDisplayLogic.ts b/src/nitro/room/object/logic/furniture/FurnitureBadgeDisplayLogic.ts new file mode 100644 index 00000000..6d96fc67 --- /dev/null +++ b/src/nitro/room/object/logic/furniture/FurnitureBadgeDisplayLogic.ts @@ -0,0 +1,78 @@ +import { RoomSpriteMouseEvent } from '../../../../../room/events/RoomSpriteMouseEvent'; +import { RoomObjectUpdateMessage } from '../../../../../room/messages/RoomObjectUpdateMessage'; +import { IRoomGeometry } from '../../../../../room/utils/IRoomGeometry'; +import { Nitro } from '../../../../Nitro'; +import { MouseEventType } from '../../../../ui/MouseEventType'; +import { RoomObjectBadgeAssetEvent } from '../../../events/RoomObjectBadgeAssetEvent'; +import { RoomObjectWidgetRequestEvent } from '../../../events/RoomObjectWidgetRequestEvent'; +import { ObjectDataUpdateMessage } from '../../../messages/ObjectDataUpdateMessage'; +import { ObjectGroupBadgeUpdateMessage } from '../../../messages/ObjectGroupBadgeUpdateMessage'; +import { StringDataType } from '../../data/type/StringDataType'; +import { RoomObjectVariable } from '../../RoomObjectVariable'; +import { FurnitureLogic } from './FurnitureLogic'; + +export class FurnitureBadgeDisplayLogic extends FurnitureLogic +{ + public getEventTypes(): string[] + { + const types = [ RoomObjectBadgeAssetEvent.LOAD_BADGE ]; + + return this.mergeTypes(super.getEventTypes(), types); + } + + public processUpdateMessage(message: RoomObjectUpdateMessage): void + { + super.processUpdateMessage(message); + + if(!this.object) return; + + if(message instanceof ObjectDataUpdateMessage) + { + const data = message.data; + + if(data instanceof StringDataType) this.updateBadge(data.getValue(1)); + + return; + } + + if(message instanceof ObjectGroupBadgeUpdateMessage) + { + if(message.assetName !== 'loading_icon') + { + this.object.model.setValue(RoomObjectVariable.FURNITURE_BADGE_ASSET_NAME, message.assetName); + this.object.model.setValue(RoomObjectVariable.FURNITURE_BADGE_IMAGE_STATUS, 1); + + this.update(Nitro.instance.time); + } + + return; + } + } + + public mouseEvent(event: RoomSpriteMouseEvent, geometry: IRoomGeometry): void + { + if(!event || !geometry || !this.object) return; + + switch(event.type) + { + case MouseEventType.DOUBLE_CLICK: + this.useObject(); + return; + default: + super.mouseEvent(event, geometry); + return; + } + } + + public useObject(): void + { + (this.object && this.eventDispatcher && this.eventDispatcher.dispatchEvent(new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.BADGE_DISPLAY_ENGRAVING, this.object))); + } + + protected updateBadge(badgeId: string): void + { + if(badgeId === '') return; + + if(this.eventDispatcher) this.eventDispatcher.dispatchEvent(new RoomObjectBadgeAssetEvent(RoomObjectBadgeAssetEvent.LOAD_BADGE, this.object, badgeId, false)); + } +} diff --git a/src/nitro/room/object/logic/furniture/FurnitureChangeStateWhenStepOnLogic.ts b/src/nitro/room/object/logic/furniture/FurnitureChangeStateWhenStepOnLogic.ts new file mode 100644 index 00000000..483fa570 --- /dev/null +++ b/src/nitro/room/object/logic/furniture/FurnitureChangeStateWhenStepOnLogic.ts @@ -0,0 +1,54 @@ +import { IAssetData } from '../../../../../core/asset/interfaces'; +import { RoomToObjectOwnAvatarMoveEvent } from '../../../events/RoomToObjectOwnAvatarMoveEvent'; +import { RoomObjectVariable } from '../../RoomObjectVariable'; +import { FurnitureLogic } from './FurnitureLogic'; + +export class FurnitureChangeStateWhenStepOnLogic extends FurnitureLogic +{ + constructor() + { + super(); + + this.onRoomToObjectOwnAvatarMoveEvent = this.onRoomToObjectOwnAvatarMoveEvent.bind(this); + } + + public initialize(asset: IAssetData): void + { + super.initialize(asset); + + if(this.eventDispatcher) this.eventDispatcher.addEventListener(RoomToObjectOwnAvatarMoveEvent.ROAME_MOVE_TO, this.onRoomToObjectOwnAvatarMoveEvent); + } + + public tearDown(): void + { + if(this.eventDispatcher) this.eventDispatcher.removeEventListener(RoomToObjectOwnAvatarMoveEvent.ROAME_MOVE_TO, this.onRoomToObjectOwnAvatarMoveEvent); + + super.tearDown(); + } + + private onRoomToObjectOwnAvatarMoveEvent(event: RoomToObjectOwnAvatarMoveEvent): void + { + if(!event || !this.object) return; + + const location = this.object.getLocation(); + const targetLocation = event.targetLocation; + + if(!targetLocation) return; + + let sizeX = this.object.model.getValue(RoomObjectVariable.FURNITURE_SIZE_X); + let sizeY = this.object.model.getValue(RoomObjectVariable.FURNITURE_SIZE_Y); + + const direction = (((Math.floor(this.object.getDirection().x) + 45) % 360) / 90); + + if((direction === 1) || (direction === 3)) [ sizeX, sizeY ] = [ sizeY, sizeX ]; + + if(((targetLocation.x >= location.x) && (targetLocation.x < (location.x + sizeX))) && ((targetLocation.y >= location.y) && (targetLocation.y < (location.y + sizeY)))) + { + this.object.setState(1, 0); + } + else + { + this.object.setState(0, 0); + } + } +} \ No newline at end of file diff --git a/src/nitro/room/object/logic/furniture/FurnitureCounterClockLogic.ts b/src/nitro/room/object/logic/furniture/FurnitureCounterClockLogic.ts new file mode 100644 index 00000000..b15ee4af --- /dev/null +++ b/src/nitro/room/object/logic/furniture/FurnitureCounterClockLogic.ts @@ -0,0 +1,54 @@ +import { RoomObjectEvent } from '../../../../../room/events/RoomObjectEvent'; +import { RoomSpriteMouseEvent } from '../../../../../room/events/RoomSpriteMouseEvent'; +import { IRoomGeometry } from '../../../../../room/utils/IRoomGeometry'; +import { MouseEventType } from '../../../../ui/MouseEventType'; +import { RoomObjectStateChangedEvent } from '../../../events/RoomObjectStateChangedEvent'; +import { FurnitureLogic } from './FurnitureLogic'; + +export class FurnitureCounterClockLogic extends FurnitureLogic +{ + public getEventTypes(): string[] + { + const types = [ RoomObjectStateChangedEvent.STATE_CHANGE ]; + + return this.mergeTypes(super.getEventTypes(), types); + } + + public mouseEvent(event: RoomSpriteMouseEvent, geometry: IRoomGeometry): void + { + if(!event|| !geometry || !this.object) return; + + let objectEvent: RoomObjectEvent = null; + + switch(event.type) + { + case MouseEventType.DOUBLE_CLICK: + switch(event.spriteTag) + { + case 'start_stop': + objectEvent = new RoomObjectStateChangedEvent(RoomObjectStateChangedEvent.STATE_CHANGE, this.object, 1); + break; + case 'reset': + objectEvent = new RoomObjectStateChangedEvent(RoomObjectStateChangedEvent.STATE_CHANGE, this.object, 2); + break; + } + + if(this.eventDispatcher && objectEvent) + { + this.eventDispatcher.dispatchEvent(objectEvent); + + return; + } + break; + } + + super.mouseEvent(event, geometry); + } + + public useObject(): void + { + if(!this.object || !this.eventDispatcher) return; + + this.eventDispatcher.dispatchEvent(new RoomObjectStateChangedEvent(RoomObjectStateChangedEvent.STATE_CHANGE, this.object, 1)); + } +} \ No newline at end of file diff --git a/src/nitro/room/object/logic/furniture/FurnitureCrackableLogic.ts b/src/nitro/room/object/logic/furniture/FurnitureCrackableLogic.ts new file mode 100644 index 00000000..f0add598 --- /dev/null +++ b/src/nitro/room/object/logic/furniture/FurnitureCrackableLogic.ts @@ -0,0 +1,19 @@ +import { RoomObjectUpdateMessage } from '../../../../../room/messages/RoomObjectUpdateMessage'; +import { RoomWidgetEnumItemExtradataParameter } from '../../../../ui/widget/enums/RoomWidgetEnumItemExtradataParameter'; +import { RoomObjectVariable } from '../../RoomObjectVariable'; +import { FurnitureLogic } from './FurnitureLogic'; + +export class FurnitureCrackableLogic extends FurnitureLogic +{ + public processUpdateMessage(message: RoomObjectUpdateMessage): void + { + super.processUpdateMessage(message); + + if(!this.object) return; + + if(this.object.model.getValue(RoomObjectVariable.FURNITURE_REAL_ROOM_OBJECT) === 1) + { + this.object.model.setValue(RoomWidgetEnumItemExtradataParameter.INFOSTAND_EXTRA_PARAM, RoomWidgetEnumItemExtradataParameter.CRACKABLE_FURNI); + } + } +} diff --git a/src/nitro/room/object/logic/furniture/FurnitureCreditLogic.ts b/src/nitro/room/object/logic/furniture/FurnitureCreditLogic.ts new file mode 100644 index 00000000..d74ae5a3 --- /dev/null +++ b/src/nitro/room/object/logic/furniture/FurnitureCreditLogic.ts @@ -0,0 +1,49 @@ +import { IAssetData } from '../../../../../core/asset/interfaces'; +import { RoomSpriteMouseEvent } from '../../../../../room/events/RoomSpriteMouseEvent'; +import { IRoomGeometry } from '../../../../../room/utils/IRoomGeometry'; +import { MouseEventType } from '../../../../ui/MouseEventType'; +import { RoomObjectWidgetRequestEvent } from '../../../events/RoomObjectWidgetRequestEvent'; +import { RoomObjectVariable } from '../../RoomObjectVariable'; +import { FurnitureLogic } from './FurnitureLogic'; + +export class FurnitureCreditLogic extends FurnitureLogic +{ + public getEventTypes(): string[] + { + const types = [ + RoomObjectWidgetRequestEvent.CREDITFURNI + ]; + + return this.mergeTypes(super.getEventTypes(), types); + } + + public initialize(asset: IAssetData): void + { + super.initialize(asset); + + let creditValue = 0; + + if(asset.credits && (asset.credits !== '') && (asset.credits.length > 0)) creditValue = parseInt(asset.credits); + + this.object.model.setValue(RoomObjectVariable.FURNITURE_CREDIT_VALUE, creditValue); + } + + public mouseEvent(event: RoomSpriteMouseEvent, geometry: IRoomGeometry): void + { + if(!event || !geometry || !this.object) return; + + switch(event.type) + { + case MouseEventType.DOUBLE_CLICK: + this.useObject(); + return; + default: + super.mouseEvent(event, geometry); + } + } + + public useObject(): void + { + (this.object && this.eventDispatcher && this.eventDispatcher.dispatchEvent(new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.CREDITFURNI, this.object))); + } +} \ No newline at end of file diff --git a/src/nitro/room/object/logic/furniture/FurnitureCustomStackHeightLogic.ts b/src/nitro/room/object/logic/furniture/FurnitureCustomStackHeightLogic.ts new file mode 100644 index 00000000..81ca33b2 --- /dev/null +++ b/src/nitro/room/object/logic/furniture/FurnitureCustomStackHeightLogic.ts @@ -0,0 +1,19 @@ +import { IAssetData } from '../../../../../core/asset/interfaces'; +import { RoomWidgetEnum } from '../../../../ui/widget/enums/RoomWidgetEnum'; +import { RoomObjectVariable } from '../../RoomObjectVariable'; +import { FurnitureMultiStateLogic } from './FurnitureMultiStateLogic'; + +export class FurnitureCustomStackHeightLogic extends FurnitureMultiStateLogic +{ + public initialize(asset: IAssetData): void + { + super.initialize(asset); + + if(this.object && this.object.model) this.object.model.setValue(RoomObjectVariable.FURNITURE_ALWAYS_STACKABLE, 1); + } + + public get widget(): string + { + return RoomWidgetEnum.CUSTOM_STACK_HEIGHT; + } +} \ No newline at end of file diff --git a/src/nitro/room/object/logic/furniture/FurnitureDiceLogic.ts b/src/nitro/room/object/logic/furniture/FurnitureDiceLogic.ts new file mode 100644 index 00000000..7fed860e --- /dev/null +++ b/src/nitro/room/object/logic/furniture/FurnitureDiceLogic.ts @@ -0,0 +1,72 @@ +import { RoomObjectEvent } from '../../../../../room/events/RoomObjectEvent'; +import { RoomSpriteMouseEvent } from '../../../../../room/events/RoomSpriteMouseEvent'; +import { IRoomGeometry } from '../../../../../room/utils/IRoomGeometry'; +import { MouseEventType } from '../../../../ui/MouseEventType'; +import { RoomObjectFurnitureActionEvent } from '../../../events/RoomObjectFurnitureActionEvent'; +import { FurnitureLogic } from './FurnitureLogic'; + +export class FurnitureDiceLogic extends FurnitureLogic +{ + private _noTags: boolean; + private _noTagsLastStateActivate: boolean; + + constructor() + { + super(); + + this._noTags = false; + this._noTagsLastStateActivate = false; + } + + public getEventTypes(): string[] + { + const types = [ RoomObjectFurnitureActionEvent.DICE_ACTIVATE, RoomObjectFurnitureActionEvent.DICE_OFF ]; + + return this.mergeTypes(super.getEventTypes(), types); + } + + public mouseEvent(event: RoomSpriteMouseEvent, geometry: IRoomGeometry): void + { + if(!event || !geometry || !this.object) return; + + let objectEvent: RoomObjectEvent = null; + + switch(event.type) + { + case MouseEventType.DOUBLE_CLICK: + if(this._noTags) + { + if(((!(this._noTagsLastStateActivate)) || (this.object.getState(0) === 0)) || (this.object.getState(0) === 100)) + { + objectEvent = new RoomObjectFurnitureActionEvent(RoomObjectFurnitureActionEvent.DICE_ACTIVATE, this.object); + + this._noTagsLastStateActivate = true; + } + else + { + objectEvent = new RoomObjectFurnitureActionEvent(RoomObjectFurnitureActionEvent.DICE_OFF, this.object); + + this._noTagsLastStateActivate = false; + } + } + else + { + if(((event.spriteTag === 'activate') || (this.object.getState(0) === 0)) || (this.object.getState(0) === 100)) + { + objectEvent = new RoomObjectFurnitureActionEvent(RoomObjectFurnitureActionEvent.DICE_ACTIVATE, this.object); + } + + else if(event.spriteTag === 'deactivate') + { + objectEvent = new RoomObjectFurnitureActionEvent(RoomObjectFurnitureActionEvent.DICE_OFF, this.object); + } + } + + if(objectEvent && this.eventDispatcher) this.eventDispatcher.dispatchEvent(objectEvent); + + return; + } + + super.mouseEvent(event, geometry); + } +} \ No newline at end of file diff --git a/src/nitro/room/object/logic/furniture/FurnitureEditableInternalLinkLogic.ts b/src/nitro/room/object/logic/furniture/FurnitureEditableInternalLinkLogic.ts new file mode 100644 index 00000000..d98c3875 --- /dev/null +++ b/src/nitro/room/object/logic/furniture/FurnitureEditableInternalLinkLogic.ts @@ -0,0 +1,83 @@ +import { IAssetData } from '../../../../../core/asset/interfaces'; +import { RoomSpriteMouseEvent } from '../../../../../room/events/RoomSpriteMouseEvent'; +import { IRoomGeometry } from '../../../../../room/utils/IRoomGeometry'; +import { MouseEventType } from '../../../../ui/MouseEventType'; +import { RoomObjectWidgetRequestEvent } from '../../../events/RoomObjectWidgetRequestEvent'; +import { RoomObjectVariable } from '../../RoomObjectVariable'; +import { FurnitureLogic } from './FurnitureLogic'; + +export class FurnitureEditableInternalLinkLogic extends FurnitureLogic +{ + private _showStateOnceRendered: boolean; + private _updateCount: number; + + constructor() + { + super(); + + this._showStateOnceRendered = false; + this._updateCount = 0; + } + + public getEventTypes(): string[] + { + const types = [ RoomObjectWidgetRequestEvent.INERNAL_LINK ]; + + return this.mergeTypes(super.getEventTypes(), types); + } + + public initialize(asset: IAssetData): void + { + super.initialize(asset); + + if(asset.action) + { + if(asset.action.startState === 1) this._showStateOnceRendered = true; + } + } + + public update(time: number): void + { + super.update(time); + + if(!this._showStateOnceRendered) return; + + this._updateCount++; + + if(this._showStateOnceRendered && (this._updateCount > 20)) + { + this.setAutomaticStateIndex(1); + + this._showStateOnceRendered = false; + } + } + + private setAutomaticStateIndex(state: number): void + { + if(!this.object) return; + + if(this.object.model) + { + this.object.model.setValue(RoomObjectVariable.FURNITURE_AUTOMATIC_STATE_INDEX, state); + } + } + + public mouseEvent(event: RoomSpriteMouseEvent, geometry: IRoomGeometry): void + { + if(!event || !geometry) return; + + if(event.type === MouseEventType.DOUBLE_CLICK) + { + this.setAutomaticStateIndex(0); + } + + super.mouseEvent(event, geometry); + } + + public useObject(): void + { + if(!this.eventDispatcher || !this.object) return; + + this.eventDispatcher.dispatchEvent(new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.INERNAL_LINK, this.object)); + } +} \ No newline at end of file diff --git a/src/nitro/room/object/logic/furniture/FurnitureEditableRoomLinkLogic.ts b/src/nitro/room/object/logic/furniture/FurnitureEditableRoomLinkLogic.ts new file mode 100644 index 00000000..b8e99806 --- /dev/null +++ b/src/nitro/room/object/logic/furniture/FurnitureEditableRoomLinkLogic.ts @@ -0,0 +1,74 @@ +import { IAssetData } from '../../../../../core/asset/interfaces'; +import { RoomObjectWidgetRequestEvent } from '../../../events/RoomObjectWidgetRequestEvent'; +import { RoomObjectVariable } from '../../RoomObjectVariable'; +import { FurnitureLogic } from './FurnitureLogic'; + +export class FurnitureEditableRoomLinkLogic extends FurnitureLogic +{ + private _timer: any; + + public getEventTypes(): string[] + { + const types = [ RoomObjectWidgetRequestEvent.ROOM_LINK ]; + + return this.mergeTypes(super.getEventTypes(), types); + } + + public initialize(asset: IAssetData): void + { + super.initialize(asset); + + if(asset.action) + { + if(asset.action.link && (asset.action.link !== '') && (asset.action.link.length > 0)) + { + (this.object && this.object.model && this.object.model.setValue(RoomObjectVariable.FURNITURE_INTERNAL_LINK, asset.action.link)); + } + } + } + + public dispose(): void + { + super.dispose(); + + if(this._timer) + { + clearTimeout(this._timer); + + this._timer = null; + } + } + + private setAutomaticStateIndex(state: number): void + { + if(!this.object) return; + + if(this.object.model) + { + this.object.model.setValue(RoomObjectVariable.FURNITURE_AUTOMATIC_STATE_INDEX, state); + } + } + + public useObject(): void + { + this.setAutomaticStateIndex(1); + + if(this._timer) + { + clearTimeout(this._timer); + + this._timer = null; + } + + this._timer = setTimeout(() => + { + this.setAutomaticStateIndex(0); + + this._timer = null; + }, 2500); + + if(!this.eventDispatcher || !this.object) return; + + this.eventDispatcher.dispatchEvent(new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.ROOM_LINK, this.object)); + } +} \ No newline at end of file diff --git a/src/nitro/room/object/logic/furniture/FurnitureExternalImageLogic.ts b/src/nitro/room/object/logic/furniture/FurnitureExternalImageLogic.ts new file mode 100644 index 00000000..cfa887d5 --- /dev/null +++ b/src/nitro/room/object/logic/furniture/FurnitureExternalImageLogic.ts @@ -0,0 +1,46 @@ +import { IAssetData } from '../../../../../core/asset/interfaces'; +import { RoomSpriteMouseEvent } from '../../../../../room/events/RoomSpriteMouseEvent'; +import { IRoomGeometry } from '../../../../../room/utils/IRoomGeometry'; +import { MouseEventType } from '../../../../ui/MouseEventType'; +import { RoomWidgetEnum } from '../../../../ui/widget/enums/RoomWidgetEnum'; +import { RoomObjectVariable } from '../../RoomObjectVariable'; +import { FurnitureMultiStateLogic } from './FurnitureMultiStateLogic'; + +export class FurnitureExternalImageLogic extends FurnitureMultiStateLogic +{ + public initialize(asset: IAssetData): void + { + super.initialize(asset); + + if(!asset) return; + + if(this.object && this.object.model) + { + let maskType = ''; + + if(asset.maskType && (asset.maskType !== '') && (asset.maskType.length > 0)) maskType = asset.maskType; + + this.object.model.setValue(RoomObjectVariable.FURNITURE_USES_PLANE_MASK, 0); + this.object.model.setValue(RoomObjectVariable.FURNITURE_PLANE_MASK_TYPE, maskType); + } + } + + public mouseEvent(event: RoomSpriteMouseEvent, geometry: IRoomGeometry): void + { + if(!event || !geometry || !this.object) return; + + switch(event.type) + { + case MouseEventType.DOUBLE_CLICK: + this.useObject(); + break; + } + + super.mouseEvent(event, geometry); + } + + public get widget(): string + { + return RoomWidgetEnum.EXTERNAL_IMAGE; + } +} \ No newline at end of file diff --git a/src/nitro/room/object/logic/furniture/FurnitureFireworksLogic.ts b/src/nitro/room/object/logic/furniture/FurnitureFireworksLogic.ts new file mode 100644 index 00000000..a32b2767 --- /dev/null +++ b/src/nitro/room/object/logic/furniture/FurnitureFireworksLogic.ts @@ -0,0 +1,6 @@ +import { FurnitureLogic } from './FurnitureLogic'; + +export class FurnitureFireworksLogic extends FurnitureLogic +{ + +} \ No newline at end of file diff --git a/src/nitro/room/object/logic/furniture/FurnitureFloorHoleLogic.ts b/src/nitro/room/object/logic/furniture/FurnitureFloorHoleLogic.ts new file mode 100644 index 00000000..1da4f465 --- /dev/null +++ b/src/nitro/room/object/logic/furniture/FurnitureFloorHoleLogic.ts @@ -0,0 +1,110 @@ +import { RoomObjectUpdateMessage } from '../../../../../room/messages/RoomObjectUpdateMessage'; +import { Vector3d } from '../../../../../room/utils/Vector3d'; +import { RoomObjectFloorHoleEvent } from '../../../events/RoomObjectFloorHoleEvent'; +import { ObjectDataUpdateMessage } from '../../../messages/ObjectDataUpdateMessage'; +import { RoomObjectVariable } from '../../RoomObjectVariable'; +import { FurnitureMultiStateLogic } from './FurnitureMultiStateLogic'; + +export class FurnitureFloorHoleLogic extends FurnitureMultiStateLogic +{ + private static _Str_9306: number = 0; + + private _currentState: number; + private _currentLocation: Vector3d; + + constructor() + { + super(); + + this._currentState = -1; + this._currentLocation = null; + } + + public getEventTypes(): string[] + { + const types = [ RoomObjectFloorHoleEvent.ADD_HOLE, RoomObjectFloorHoleEvent.REMOVE_HOLE ]; + + return this.mergeTypes(super.getEventTypes(), types); + } + + public dispose(): void + { + if(this._currentState === FurnitureFloorHoleLogic._Str_9306) + { + this.eventDispatcher.dispatchEvent(new RoomObjectFloorHoleEvent(RoomObjectFloorHoleEvent.REMOVE_HOLE, this.object)); + } + + super.dispose(); + } + + public update(time: number): void + { + super.update(time); + + this._Str_25016(); + } + + public processUpdateMessage(message: RoomObjectUpdateMessage): void + { + super.processUpdateMessage(message); + + if(!this.object) return; + + if(message instanceof ObjectDataUpdateMessage) + { + this._Str_21445(this.object.getState(0)); + } + + const location = this.object.getLocation(); + + if(!this._currentLocation) + { + this._currentLocation = new Vector3d(); + } + else + { + if((location.x !== this._currentLocation.x) || (location.y !== this._currentLocation.y)) + { + if(this._currentState === FurnitureFloorHoleLogic._Str_9306) + { + if(this.eventDispatcher) this.eventDispatcher.dispatchEvent(new RoomObjectFloorHoleEvent(RoomObjectFloorHoleEvent.ADD_HOLE, this.object)); + } + } + } + + this._currentLocation.assign(location); + } + + private _Str_21445(state: number): void + { + if(state === this._currentState) return; + + if(this.eventDispatcher) + { + if(state === FurnitureFloorHoleLogic._Str_9306) + { + this.eventDispatcher.dispatchEvent(new RoomObjectFloorHoleEvent(RoomObjectFloorHoleEvent.ADD_HOLE, this.object)); + } + + else if(this._currentState === FurnitureFloorHoleLogic._Str_9306) + { + this.eventDispatcher.dispatchEvent(new RoomObjectFloorHoleEvent(RoomObjectFloorHoleEvent.REMOVE_HOLE, this.object)); + } + } + + this._currentState = state; + } + + private _Str_25016(): void + { + if(!this.object) return; + + const model = this.object.model; + + if(!model) return; + + const stateIndex = model.getValue(RoomObjectVariable.FURNITURE_AUTOMATIC_STATE_INDEX); + + if(!isNaN(stateIndex)) this._Str_21445((stateIndex % 2)); + } +} \ No newline at end of file diff --git a/src/nitro/room/object/logic/furniture/FurnitureFriendLogic.ts b/src/nitro/room/object/logic/furniture/FurnitureFriendLogic.ts new file mode 100644 index 00000000..527ea0f0 --- /dev/null +++ b/src/nitro/room/object/logic/furniture/FurnitureFriendLogic.ts @@ -0,0 +1,72 @@ +import { FurnitureMultiStateLogic } from './FurnitureMultiStateLogic'; +import { RoomObjectBadgeAssetEvent } from '../../../events/RoomObjectBadgeAssetEvent'; +import { RoomObjectWidgetRequestEvent } from '../../../events/RoomObjectWidgetRequestEvent'; +import { IAssetData } from '../../../../../core/asset/interfaces'; +import { RoomObjectVariable } from '../../RoomObjectVariable'; +import { RoomObjectUpdateMessage } from '../../../../../room/messages/RoomObjectUpdateMessage'; +import { ObjectDataUpdateMessage } from '../../../messages/ObjectDataUpdateMessage'; +import { StringDataType } from '../../data/type/StringDataType'; + +export class FurnitureFriendLogic extends FurnitureMultiStateLogic +{ + private static readonly STATE_UNINITIALIZED: number = -1; + private static readonly STATE_UNLOCKED: number = 0; + private static readonly STATE_LOCKED: number = 1; + + private _state: number = -1; + + public get engravingDialogType(): number + { + return 0; + } + + public initialize(asset: IAssetData): void + { + super.initialize(asset); + if(this.object) this.object.model.setValue(RoomObjectVariable.FURNITURE_FRIENDFURNI_ENGRAVING, this.engravingDialogType); + } + + public processUpdateMessage(message: RoomObjectUpdateMessage): void + { + // chheck if not ObjectSelectedMessage + const dataMessage = message; + if(message instanceof ObjectDataUpdateMessage) + { + const local4 = dataMessage.data; + if(local4) + { + this._state = local4.state; + } + else + { + this._state =dataMessage.state; + } + + } + + super.processUpdateMessage(message); + + } + + public getEventTypes(): string[] + { + const types = [ RoomObjectWidgetRequestEvent.FRIEND_FURNITURE_ENGRAVING ]; + + return this.mergeTypes(super.getEventTypes(), types); + } + + public useObject(): void + { + if(this._state == FurnitureFriendLogic.STATE_LOCKED) + { + (this.object && this.eventDispatcher && this.eventDispatcher.dispatchEvent(new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.FRIEND_FURNITURE_ENGRAVING, this.object))); + } + else + { + super.useObject(); + } + + } +} + + diff --git a/src/nitro/room/object/logic/furniture/FurnitureGuildCustomizedLogic.ts b/src/nitro/room/object/logic/furniture/FurnitureGuildCustomizedLogic.ts new file mode 100644 index 00000000..a62d3df8 --- /dev/null +++ b/src/nitro/room/object/logic/furniture/FurnitureGuildCustomizedLogic.ts @@ -0,0 +1,46 @@ +import { RoomObjectUpdateMessage } from '../../../../../room/messages/RoomObjectUpdateMessage'; +import { ObjectDataUpdateMessage } from '../../../messages/ObjectDataUpdateMessage'; +import { StringDataType } from '../../data/type/StringDataType'; +import { RoomObjectVariable } from '../../RoomObjectVariable'; +import { FurnitureMultiStateLogic } from './FurnitureMultiStateLogic'; + +export class FurnitureGuildCustomizedLogic extends FurnitureMultiStateLogic +{ + public static GROUPID_KEY: number = 1; + public static BADGE_KEY: number = 2; + public static COLOR1_KEY: number = 3; + public static COLOR2_KEY: number = 4; + + public processUpdateMessage(message: RoomObjectUpdateMessage): void + { + super.processUpdateMessage(message); + + if(message instanceof ObjectDataUpdateMessage) + { + const data = message.data; + + if(data instanceof StringDataType) + { + this.updateGroupId(data.getValue(FurnitureGuildCustomizedLogic.GROUPID_KEY)); + this.updateBadge(data.getValue(FurnitureGuildCustomizedLogic.BADGE_KEY)); + this.updateColors(data.getValue(FurnitureGuildCustomizedLogic.COLOR1_KEY), data.getValue(FurnitureGuildCustomizedLogic.COLOR2_KEY)); + } + } + } + + private updateGroupId(id: string): void + { + this.object.model.setValue(RoomObjectVariable.FURNITURE_GUILD_CUSTOMIZED_GUILD_ID, parseInt(id)); + } + + private updateBadge(badge: string): void + { + this.object.model.setValue(RoomObjectVariable.FURNITURE_GUILD_CUSTOMIZED_BADGE, badge); + } + + public updateColors(color1: string, color2: string): void + { + this.object.model.setValue(RoomObjectVariable.FURNITURE_GUILD_CUSTOMIZED_COLOR_1, parseInt(color1, 16)); + this.object.model.setValue(RoomObjectVariable.FURNITURE_GUILD_CUSTOMIZED_COLOR_2, parseInt(color2, 16)); + } +} \ No newline at end of file diff --git a/src/nitro/room/object/logic/furniture/FurnitureHabboWheelLogic.ts b/src/nitro/room/object/logic/furniture/FurnitureHabboWheelLogic.ts new file mode 100644 index 00000000..49b4c0c5 --- /dev/null +++ b/src/nitro/room/object/logic/furniture/FurnitureHabboWheelLogic.ts @@ -0,0 +1,40 @@ +import { RoomSpriteMouseEvent } from '../../../../../room/events/RoomSpriteMouseEvent'; +import { IRoomGeometry } from '../../../../../room/utils/IRoomGeometry'; +import { MouseEventType } from '../../../../ui/MouseEventType'; +import { RoomObjectFurnitureActionEvent } from '../../../events/RoomObjectFurnitureActionEvent'; +import { FurnitureLogic } from './FurnitureLogic'; + +export class FurnitureHabboWheelLogic extends FurnitureLogic +{ + public getEventTypes(): string[] + { + const types = [ RoomObjectFurnitureActionEvent.USE_HABBOWHEEL ]; + + return this.mergeTypes(super.getEventTypes(), types); + } + + public mouseEvent(event: RoomSpriteMouseEvent, geometry: IRoomGeometry): void + { + if(!event || !geometry || !this.object) return; + + switch(event.type) + { + case MouseEventType.DOUBLE_CLICK: + this.useObject(); + return; + default: + super.mouseEvent(event, geometry); + return; + } + } + + public useObject(): void + { + if(!this.object) return; + + if(this.eventDispatcher) + { + this.eventDispatcher.dispatchEvent(new RoomObjectFurnitureActionEvent(RoomObjectFurnitureActionEvent.USE_HABBOWHEEL, this.object)); + } + } +} \ No newline at end of file diff --git a/src/nitro/room/object/logic/furniture/FurnitureHighScoreLogic.ts b/src/nitro/room/object/logic/furniture/FurnitureHighScoreLogic.ts new file mode 100644 index 00000000..5ccc5fdc --- /dev/null +++ b/src/nitro/room/object/logic/furniture/FurnitureHighScoreLogic.ts @@ -0,0 +1,65 @@ +import { RoomSpriteMouseEvent } from '../../../../../room/events/RoomSpriteMouseEvent'; +import { RoomObjectUpdateMessage } from '../../../../../room/messages/RoomObjectUpdateMessage'; +import { IRoomGeometry } from '../../../../../room/utils/IRoomGeometry'; +import { MouseEventType } from '../../../../ui/MouseEventType'; +import { RoomObjectWidgetRequestEvent } from '../../../events/RoomObjectWidgetRequestEvent'; +import { ObjectDataUpdateMessage } from '../../../messages/ObjectDataUpdateMessage'; +import { RoomObjectVariable } from '../../RoomObjectVariable'; +import { FurnitureLogic } from './FurnitureLogic'; + +export class FurnitureHighScoreLogic extends FurnitureLogic +{ + private static SHOW_WIDGET_IN_STATE = 1; + + private _state = -1; + + public getEventTypes(): string[] + { + return [ RoomObjectWidgetRequestEvent.HIGH_SCORE_DISPLAY, RoomObjectWidgetRequestEvent.HIDE_HIGH_SCORE_DISPLAY ]; + } + + public tearDown(): void + { + if(this.object.model.getValue(RoomObjectVariable.FURNITURE_REAL_ROOM_OBJECT) === 1) + { + this.eventDispatcher.dispatchEvent(new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.HIDE_HIGH_SCORE_DISPLAY, this.object)); + } + + super.tearDown(); + } + + public processUpdateMessage(message: RoomObjectUpdateMessage): void + { + super.processUpdateMessage(message); + + if(this.object.model.getValue(RoomObjectVariable.FURNITURE_REAL_ROOM_OBJECT) !== 1) return; + + if(message instanceof ObjectDataUpdateMessage) + { + if(message.state === FurnitureHighScoreLogic.SHOW_WIDGET_IN_STATE) + { + this.eventDispatcher.dispatchEvent(new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.HIGH_SCORE_DISPLAY, this.object)); + } + else + { + this.eventDispatcher.dispatchEvent(new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.HIDE_HIGH_SCORE_DISPLAY, this.object)); + } + + this._state = message.state; + } + } + + public mouseEvent(event: RoomSpriteMouseEvent, geometry: IRoomGeometry): void + { + if(!event || !geometry || !this.object) return; + + switch(event.type) + { + case MouseEventType.DOUBLE_CLICK: + this.useObject(); + return; + default: + super.mouseEvent(event, geometry); + } + } +} \ No newline at end of file diff --git a/src/nitro/room/object/logic/furniture/FurnitureHockeyScoreLogic.ts b/src/nitro/room/object/logic/furniture/FurnitureHockeyScoreLogic.ts new file mode 100644 index 00000000..d75ff426 --- /dev/null +++ b/src/nitro/room/object/logic/furniture/FurnitureHockeyScoreLogic.ts @@ -0,0 +1,62 @@ +import { RoomObjectEvent } from '../../../../../room/events/RoomObjectEvent'; +import { RoomSpriteMouseEvent } from '../../../../../room/events/RoomSpriteMouseEvent'; +import { IRoomGeometry } from '../../../../../room/utils/IRoomGeometry'; +import { MouseEventType } from '../../../../ui/MouseEventType'; +import { RoomObjectStateChangedEvent } from '../../../events/RoomObjectStateChangedEvent'; +import { FurnitureLogic } from './FurnitureLogic'; + +export class FurnitureHockeyScoreLogic extends FurnitureLogic +{ + public getEventTypes(): string[] + { + const types = [ RoomObjectStateChangedEvent.STATE_CHANGE ]; + + return this.mergeTypes(super.getEventTypes(), types); + } + + public mouseEvent(event: RoomSpriteMouseEvent, geometry: IRoomGeometry): void + { + if(!event || !geometry || !this.object) return; + + let objectEvent: RoomObjectEvent = null; + + switch(event.type) + { + case MouseEventType.DOUBLE_CLICK: + switch(event.spriteTag) + { + case 'off': + objectEvent = new RoomObjectStateChangedEvent(RoomObjectStateChangedEvent.STATE_CHANGE, this.object, 3); + break; + } + break; + case MouseEventType.MOUSE_CLICK: + switch(event.spriteTag) + { + case 'inc': + objectEvent = new RoomObjectStateChangedEvent(RoomObjectStateChangedEvent.STATE_CHANGE, this.object, 2); + break; + case 'dec': + objectEvent = new RoomObjectStateChangedEvent(RoomObjectStateChangedEvent.STATE_CHANGE, this.object, 1); + break; + } + break; + } + + if(this.eventDispatcher && objectEvent) + { + this.eventDispatcher.dispatchEvent(objectEvent); + + return; + } + + super.mouseEvent(event, geometry); + } + + public useObject(): void + { + if(!this.object || !this.eventDispatcher) return; + + this.eventDispatcher.dispatchEvent(new RoomObjectStateChangedEvent(RoomObjectStateChangedEvent.STATE_CHANGE, this.object, 3)); + } +} \ No newline at end of file diff --git a/src/nitro/room/object/logic/furniture/FurnitureIceStormLogic.ts b/src/nitro/room/object/logic/furniture/FurnitureIceStormLogic.ts new file mode 100644 index 00000000..56a19b5a --- /dev/null +++ b/src/nitro/room/object/logic/furniture/FurnitureIceStormLogic.ts @@ -0,0 +1,65 @@ +import { RoomObjectUpdateMessage } from '../../../../../room/messages/RoomObjectUpdateMessage'; +import { ObjectDataUpdateMessage } from '../../../messages/ObjectDataUpdateMessage'; +import { LegacyDataType } from '../../data/type/LegacyDataType'; +import { FurnitureMultiStateLogic } from './FurnitureMultiStateLogic'; + +export class FurnitureIceStormLogic extends FurnitureMultiStateLogic +{ + private _nextState: number; + private _nextStateTimestamp: number; + + constructor() + { + super(); + + this._nextState = 0; + this._nextStateTimestamp = 0; + } + + public update(totalTimeRunning: number): void + { + if((this._nextStateTimestamp > 0) && (totalTimeRunning >= this._nextStateTimestamp)) + { + this._nextStateTimestamp = 0; + + const data = new LegacyDataType(); + + data.setString(this._nextState.toString()); + + super.processUpdateMessage(new ObjectDataUpdateMessage(this._nextState, data)); + } + + super.update(totalTimeRunning); + } + + public processUpdateMessage(message: RoomObjectUpdateMessage): void + { + if(message instanceof ObjectDataUpdateMessage) return this.processUpdate(message); + + super.processUpdateMessage(message); + } + + private processUpdate(message: ObjectDataUpdateMessage): void + { + if(!message) return; + + const state = message.state / 1000; + const time = message.state % 1000; + + if(!time) + { + this._nextStateTimestamp = 0; + + const data = new LegacyDataType(); + + data.setString(state.toString()); + + super.processUpdateMessage(new ObjectDataUpdateMessage(state, data)); + } + else + { + this._nextState = state; + this._nextStateTimestamp = this.time + time; + } + } +} \ No newline at end of file diff --git a/src/nitro/room/object/logic/furniture/FurnitureLogic.ts b/src/nitro/room/object/logic/furniture/FurnitureLogic.ts new file mode 100644 index 00000000..c3e70a6d --- /dev/null +++ b/src/nitro/room/object/logic/furniture/FurnitureLogic.ts @@ -0,0 +1,374 @@ +import { IAssetData } from '../../../../../core/asset/interfaces'; +import { RoomObjectMouseEvent } from '../../../../../room/events/RoomObjectMouseEvent'; +import { RoomSpriteMouseEvent } from '../../../../../room/events/RoomSpriteMouseEvent'; +import { RoomObjectUpdateMessage } from '../../../../../room/messages/RoomObjectUpdateMessage'; +import { IRoomObjectController } from '../../../../../room/object/IRoomObjectController'; +import { IRoomObjectModel } from '../../../../../room/object/IRoomObjectModel'; +import { IRoomGeometry } from '../../../../../room/utils/IRoomGeometry'; +import { IVector3D } from '../../../../../room/utils/IVector3D'; +import { Vector3d } from '../../../../../room/utils/Vector3d'; +import { MouseEventType } from '../../../../ui/MouseEventType'; +import { RoomObjectStateChangedEvent } from '../../../events/RoomObjectStateChangedEvent'; +import { RoomObjectWidgetRequestEvent } from '../../../events/RoomObjectWidgetRequestEvent'; +import { ObjectDataUpdateMessage } from '../../../messages/ObjectDataUpdateMessage'; +import { ObjectHeightUpdateMessage } from '../../../messages/ObjectHeightUpdateMessage'; +import { ObjectItemDataUpdateMessage } from '../../../messages/ObjectItemDataUpdateMessage'; +import { ObjectMoveUpdateMessage } from '../../../messages/ObjectMoveUpdateMessage'; +import { ObjectSelectedMessage } from '../../../messages/ObjectSelectedMessage'; +import { RoomObjectVariable } from '../../RoomObjectVariable'; +import { MovingObjectLogic } from '../MovingObjectLogic'; + +export class FurnitureLogic extends MovingObjectLogic +{ + private static BOUNCING_STEPS: number = 8; + private static BOUNCING_Z: number = 0.0625; + + private _sizeX: number; + private _sizeY: number; + private _sizeZ: number; + private _centerX: number; + private _centerY: number; + private _centerZ: number; + + private _directions: number[]; + + private _mouseOver: boolean; + + private _locationOffset: IVector3D; + private _bouncingStep: number; + private _storedRotateMessage: RoomObjectUpdateMessage; + private _directionInitialized: boolean; + + constructor() + { + super(); + + this._sizeX = 0; + this._sizeY = 0; + this._sizeZ = 0; + this._centerX = 0; + this._centerY = 0; + this._centerZ = 0; + + this._directions = []; + + this._mouseOver = false; + + this._locationOffset = new Vector3d(); + this._bouncingStep = 0; + this._storedRotateMessage = null; + this._directionInitialized = false; + } + + public getEventTypes(): string[] + { + const types = [ RoomObjectStateChangedEvent.STATE_CHANGE, RoomObjectMouseEvent.CLICK, RoomObjectMouseEvent.MOUSE_DOWN ]; + + if(this.widget) types.push(RoomObjectWidgetRequestEvent.OPEN_WIDGET, RoomObjectWidgetRequestEvent.CLOSE_WIDGET); + + if(this.contextMenu) types.push(RoomObjectWidgetRequestEvent.OPEN_FURNI_CONTEXT_MENU, RoomObjectWidgetRequestEvent.CLOSE_FURNI_CONTEXT_MENU); + + return this.mergeTypes(super.getEventTypes(), types); + } + + public initialize(asset: IAssetData): void + { + if(!asset) return; + + const model = this.object && this.object.model; + + if(!model) return; + + const dimensions = asset.dimensions; + + if(!dimensions) return; + + this._sizeX = dimensions.x; + this._sizeY = dimensions.y; + this._sizeZ = dimensions.z; + + this._centerX = (this._sizeX / 2); + this._centerY = (this._sizeY / 2); + this._centerZ = (this._sizeZ / 2); + + const directions = asset.directions; + + if(directions && directions.length) + { + for(const direction of directions) this._directions.push(direction); + + this._directions.sort((a, b) => + { + return a - b; + }); + } + + model.setValue(RoomObjectVariable.FURNITURE_SIZE_X, this._sizeX); + model.setValue(RoomObjectVariable.FURNITURE_SIZE_Y, this._sizeY); + model.setValue(RoomObjectVariable.FURNITURE_SIZE_Z, this._sizeZ); + model.setValue(RoomObjectVariable.FURNITURE_CENTER_X, this._centerX); + model.setValue(RoomObjectVariable.FURNITURE_CENTER_Y, this._centerY); + model.setValue(RoomObjectVariable.FURNITURE_CENTER_Z, this._centerZ); + model.setValue(RoomObjectVariable.FURNITURE_ALLOWED_DIRECTIONS, this._directions); + model.setValue(RoomObjectVariable.FURNITURE_ALPHA_MULTIPLIER, 1); + } + + public dispose(): void + { + super.dispose(); + + this._storedRotateMessage = null; + this._directions = null; + } + + public setObject(object: IRoomObjectController): void + { + super.setObject(object); + + if(object && object.getLocation().length) this._directionInitialized = true; + } + + protected getAdClickUrl(model: IRoomObjectModel): string + { + return model.getValue(RoomObjectVariable.FURNITURE_AD_URL); + } + + public update(time: number): void + { + super.update(time); + + if(this._bouncingStep > 0) + { + this._bouncingStep++; + + if(this._bouncingStep > FurnitureLogic.BOUNCING_STEPS) this._bouncingStep = 0; + } + } + + public processUpdateMessage(message: RoomObjectUpdateMessage): void + { + if(message instanceof ObjectDataUpdateMessage) + { + this.processDataUpdateMessage(message); + + return; + } + + if(message instanceof ObjectHeightUpdateMessage) + { + this.processObjectHeightUpdateMessage(message); + + return; + } + + if(message instanceof ObjectItemDataUpdateMessage) + { + this.processItemDataUpdateMessage(message); + + return; + } + + this._mouseOver = false; + + if(message.location && message.direction) + { + if(!(message instanceof ObjectMoveUpdateMessage)) + { + const direction = this.object.getDirection(); + const location = this.object.getLocation(); + + if((direction.x !== message.direction.x) && this._directionInitialized) + { + if((location.x === message.location.x) && (location.y === message.location.y) && (location.z === message.location.z)) + { + this._bouncingStep = 1; + this._storedRotateMessage = new RoomObjectUpdateMessage(message.location, message.direction); + + message = null; + } + } + } + + this._directionInitialized = true; + } + + if(message instanceof ObjectSelectedMessage) + { + if(this.contextMenu && this.eventDispatcher && this.object) + { + const eventType = (message.selected) ? RoomObjectWidgetRequestEvent.OPEN_FURNI_CONTEXT_MENU : RoomObjectWidgetRequestEvent.CLOSE_FURNI_CONTEXT_MENU; + + this.eventDispatcher.dispatchEvent(new RoomObjectWidgetRequestEvent(eventType, this.object)); + } + } + + super.processUpdateMessage(message); + } + + private processDataUpdateMessage(message: ObjectDataUpdateMessage): void + { + if(!message) return; + + this.object.setState(message.state, 0); + + if(message.data) message.data.writeRoomObjectModel(this.object.model); + + if(!isNaN(message.extra)) this.object.model.setValue(RoomObjectVariable.FURNITURE_EXTRAS, message.extra.toString()); + + this.object.model.setValue(RoomObjectVariable.FURNITURE_STATE_UPDATE_TIME, this.lastUpdateTime); + } + + private processObjectHeightUpdateMessage(message: ObjectHeightUpdateMessage): void + { + if(!message) return; + + this.object.model.setValue(RoomObjectVariable.FURNITURE_SIZE_Z, message.height); + } + + private processItemDataUpdateMessage(message: ObjectItemDataUpdateMessage): void + { + if(!message) return; + + this.object.model.setValue(RoomObjectVariable.FURNITURE_ITEMDATA, message.data); + } + + public mouseEvent(event: RoomSpriteMouseEvent, geometry: IRoomGeometry): void + { + const adUrl = this.getAdClickUrl(this.object.model); + + switch(event.type) + { + case MouseEventType.MOUSE_MOVE: + if(this.eventDispatcher) + { + const mouseEvent = new RoomObjectMouseEvent(RoomObjectMouseEvent.MOUSE_MOVE, this.object, event._Str_3463, event.altKey, event.ctrlKey, event.shiftKey, event.buttonDown); + + mouseEvent.localX = event.localX; + mouseEvent.localY = event.localY; + mouseEvent.spriteOffsetX = event.spriteOffsetX; + mouseEvent.spriteOffsetY = event.spriteOffsetY; + + this.eventDispatcher.dispatchEvent(mouseEvent); + } + return; + case MouseEventType.ROLL_OVER: + if(!this._mouseOver) + { + if(this.eventDispatcher) + { + const mouseEvent = new RoomObjectMouseEvent(RoomObjectMouseEvent.MOUSE_ENTER, this.object, event._Str_3463, event.altKey, event.ctrlKey, event.shiftKey, event.buttonDown); + + mouseEvent.localX = event.localX; + mouseEvent.localY = event.localY; + mouseEvent.spriteOffsetX = event.spriteOffsetX; + mouseEvent.spriteOffsetY = event.spriteOffsetY; + + this.eventDispatcher.dispatchEvent(mouseEvent); + } + + this._mouseOver = true; + } + return; + case MouseEventType.ROLL_OUT: + if(this._mouseOver) + { + if(this.eventDispatcher) + { + const mouseEvent = new RoomObjectMouseEvent(RoomObjectMouseEvent.MOUSE_LEAVE, this.object, event._Str_3463, event.altKey, event.ctrlKey, event.shiftKey, event.buttonDown); + + mouseEvent.localX = event.localX; + mouseEvent.localY = event.localY; + mouseEvent.spriteOffsetX = event.spriteOffsetX; + mouseEvent.spriteOffsetY = event.spriteOffsetY; + + this.eventDispatcher.dispatchEvent(mouseEvent); + } + + this._mouseOver = false; + } + return; + case MouseEventType.DOUBLE_CLICK: + this.useObject(); + return; + case MouseEventType.MOUSE_CLICK: + if(this.eventDispatcher) + { + const mouseEvent = new RoomObjectMouseEvent(RoomObjectMouseEvent.CLICK, this.object, event._Str_3463, event.altKey, event.ctrlKey, event.shiftKey, event.buttonDown); + + mouseEvent.localX = event.localX; + mouseEvent.localY = event.localY; + mouseEvent.spriteOffsetX = event.spriteOffsetX; + mouseEvent.spriteOffsetY = event.spriteOffsetY; + + this.eventDispatcher.dispatchEvent(mouseEvent); + } + + if(this.eventDispatcher && this.object && this.contextMenu) + { + this.eventDispatcher.dispatchEvent(new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.OPEN_FURNI_CONTEXT_MENU, this.object)); + } + return; + case MouseEventType.MOUSE_DOWN: + if(this.eventDispatcher) + { + const mouseEvent = new RoomObjectMouseEvent(RoomObjectMouseEvent.MOUSE_DOWN, this.object, event._Str_3463, event.altKey, event.ctrlKey, event.shiftKey, event.buttonDown); + + this.eventDispatcher.dispatchEvent(mouseEvent); + } + return; + } + } + + protected getLocationOffset(): IVector3D + { + if(this._bouncingStep <= 0) return null; + + this._locationOffset.x = 0; + this._locationOffset.y = 0; + + if(this._bouncingStep <= (FurnitureLogic.BOUNCING_STEPS / 2)) + { + this._locationOffset.z = FurnitureLogic.BOUNCING_Z * this._bouncingStep; + } + else + { + if(this._bouncingStep <= FurnitureLogic.BOUNCING_STEPS) + { + if(this._storedRotateMessage) + { + super.processUpdateMessage(this._storedRotateMessage); + + this._storedRotateMessage = null; + } + + this._locationOffset.z = FurnitureLogic.BOUNCING_Z * (FurnitureLogic.BOUNCING_STEPS - this._bouncingStep); + } + } + + return this._locationOffset; + } + + public useObject(): void + { + if(!this.object) return; + + const adUrl = this.getAdClickUrl(this.object.model); + + if(this.eventDispatcher) + { + if(this.widget) this.eventDispatcher.dispatchEvent(new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.OPEN_WIDGET, this.object)); + + this.eventDispatcher.dispatchEvent(new RoomObjectStateChangedEvent(RoomObjectStateChangedEvent.STATE_CHANGE, this.object)); + } + } + + public tearDown(): void + { + if(this.widget && (this.object.model.getValue(RoomObjectVariable.FURNITURE_REAL_ROOM_OBJECT) === 1)) + { + this.eventDispatcher.dispatchEvent(new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.CLOSE_WIDGET, this.object)); + } + + super.tearDown(); + } +} \ No newline at end of file diff --git a/src/nitro/room/object/logic/furniture/FurnitureMannequinLogic.ts b/src/nitro/room/object/logic/furniture/FurnitureMannequinLogic.ts new file mode 100644 index 00000000..9e0b57c9 --- /dev/null +++ b/src/nitro/room/object/logic/furniture/FurnitureMannequinLogic.ts @@ -0,0 +1,69 @@ +import { RoomSpriteMouseEvent } from '../../../../../room/events/RoomSpriteMouseEvent'; +import { RoomObjectUpdateMessage } from '../../../../../room/messages/RoomObjectUpdateMessage'; +import { IRoomGeometry } from '../../../../../room/utils/IRoomGeometry'; +import { MouseEventType } from '../../../../ui/MouseEventType'; +import { RoomObjectWidgetRequestEvent } from '../../../events/RoomObjectWidgetRequestEvent'; +import { ObjectDataUpdateMessage } from '../../../messages/ObjectDataUpdateMessage'; +import { MapDataType } from '../../data/type/MapDataType'; +import { RoomObjectVariable } from '../../RoomObjectVariable'; +import { FurnitureLogic } from './FurnitureLogic'; + +export class FurnitureMannequinLogic extends FurnitureLogic +{ + private static GENDER: string = 'GENDER'; + private static FIGURE: string = 'FIGURE'; + private static OUTFIT_NAME: string = 'OUTFIT_NAME'; + + public getEventTypes(): string[] + { + const types = [ RoomObjectWidgetRequestEvent.MANNEQUIN ]; + + return this.mergeTypes(super.getEventTypes(), types); + } + + public processUpdateMessage(message: RoomObjectUpdateMessage): void + { + super.processUpdateMessage(message); + + if(message instanceof ObjectDataUpdateMessage) + { + message.data.writeRoomObjectModel(this.object.model); + + this.processObjectData(); + } + } + + private processObjectData(): void + { + if(!this.object || !this.object.model) return; + + const data = new MapDataType(); + + data.initializeFromRoomObjectModel(this.object.model); + + this.object.model.setValue(RoomObjectVariable.FURNITURE_MANNEQUIN_GENDER, data.getValue(FurnitureMannequinLogic.GENDER)); + this.object.model.setValue(RoomObjectVariable.FURNITURE_MANNEQUIN_FIGURE, data.getValue(FurnitureMannequinLogic.FIGURE)); + this.object.model.setValue(RoomObjectVariable.FURNITURE_MANNEQUIN_NAME, data.getValue(FurnitureMannequinLogic.OUTFIT_NAME)); + } + + public mouseEvent(event: RoomSpriteMouseEvent, geometry: IRoomGeometry): void + { + if(!event || !geometry || !this.object) return; + + switch(event.type) + { + case MouseEventType.DOUBLE_CLICK: + this.useObject(); + return; + } + + super.mouseEvent(event, geometry); + } + + public useObject(): void + { + if(!this.eventDispatcher || !this.object) return; + + this.eventDispatcher.dispatchEvent(new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.MANNEQUIN, this.object)); + } +} \ No newline at end of file diff --git a/src/nitro/room/object/logic/furniture/FurnitureMultiHeightLogic.ts b/src/nitro/room/object/logic/furniture/FurnitureMultiHeightLogic.ts new file mode 100644 index 00000000..ac9e6dbd --- /dev/null +++ b/src/nitro/room/object/logic/furniture/FurnitureMultiHeightLogic.ts @@ -0,0 +1,13 @@ +import { IAssetData } from '../../../../../core/asset/interfaces'; +import { RoomObjectVariable } from '../../RoomObjectVariable'; +import { FurnitureMultiStateLogic } from './FurnitureMultiStateLogic'; + +export class FurnitureMultiHeightLogic extends FurnitureMultiStateLogic +{ + public initialize(asset: IAssetData): void + { + super.initialize(asset); + + if(this.object && this.object.model) this.object.model.setValue(RoomObjectVariable.FURNITURE_IS_VARIABLE_HEIGHT, 1); + } +} \ No newline at end of file diff --git a/src/nitro/room/object/logic/furniture/FurnitureMultiStateLogic.ts b/src/nitro/room/object/logic/furniture/FurnitureMultiStateLogic.ts new file mode 100644 index 00000000..39b8d59d --- /dev/null +++ b/src/nitro/room/object/logic/furniture/FurnitureMultiStateLogic.ts @@ -0,0 +1,32 @@ +import { RoomSpriteMouseEvent } from '../../../../../room/events/RoomSpriteMouseEvent'; +import { IRoomGeometry } from '../../../../../room/utils/IRoomGeometry'; +import { MouseEventType } from '../../../../ui/MouseEventType'; +import { RoomObjectFurnitureActionEvent } from '../../../events/RoomObjectFurnitureActionEvent'; +import { FurnitureLogic } from './FurnitureLogic'; + +export class FurnitureMultiStateLogic extends FurnitureLogic +{ + public getEventTypes(): string[] + { + const types = [ RoomObjectFurnitureActionEvent.MOUSE_BUTTON, RoomObjectFurnitureActionEvent.MOUSE_ARROW ]; + + return this.mergeTypes(super.getEventTypes(), types); + } + + public mouseEvent(event: RoomSpriteMouseEvent, geometry: IRoomGeometry): void + { + if(!event || !geometry || !this.object) return; + + switch(event.type) + { + case MouseEventType.ROLL_OVER: + this.eventDispatcher && this.eventDispatcher.dispatchEvent(new RoomObjectFurnitureActionEvent(RoomObjectFurnitureActionEvent.MOUSE_BUTTON, this.object)); + break; + case MouseEventType.ROLL_OUT: + this.eventDispatcher && this.eventDispatcher.dispatchEvent(new RoomObjectFurnitureActionEvent(RoomObjectFurnitureActionEvent.MOUSE_ARROW, this.object)); + break; + } + + super.mouseEvent(event, geometry); + } +} \ No newline at end of file diff --git a/src/nitro/room/object/logic/furniture/FurnitureOneWayDoorLogic.ts b/src/nitro/room/object/logic/furniture/FurnitureOneWayDoorLogic.ts new file mode 100644 index 00000000..5e3a8b14 --- /dev/null +++ b/src/nitro/room/object/logic/furniture/FurnitureOneWayDoorLogic.ts @@ -0,0 +1,37 @@ +import { RoomSpriteMouseEvent } from '../../../../../room/events/RoomSpriteMouseEvent'; +import { IRoomGeometry } from '../../../../../room/utils/IRoomGeometry'; +import { MouseEventType } from '../../../../ui/MouseEventType'; +import { RoomObjectFurnitureActionEvent } from '../../../events/RoomObjectFurnitureActionEvent'; +import { FurnitureLogic } from './FurnitureLogic'; + +export class FurnitureOneWayDoorLogic extends FurnitureLogic +{ + public getEventTypes(): string[] + { + const types = [ RoomObjectFurnitureActionEvent.ENTER_ONEWAYDOOR ]; + + return this.mergeTypes(super.getEventTypes(), types); + } + + public mouseEvent(event: RoomSpriteMouseEvent, geometry: IRoomGeometry): void + { + if(!event || !geometry || !this.object) return; + + switch(event.type) + { + case MouseEventType.DOUBLE_CLICK: + this.useObject(); + + return; + } + + super.mouseEvent(event, geometry); + } + + public useObject(): void + { + if(!this.object) return; + + if(this.eventDispatcher) this.eventDispatcher.dispatchEvent(new RoomObjectFurnitureActionEvent(RoomObjectFurnitureActionEvent.ENTER_ONEWAYDOOR, this.object)); + } +} \ No newline at end of file diff --git a/src/nitro/room/object/logic/furniture/FurniturePetCustomizationLogic.ts b/src/nitro/room/object/logic/furniture/FurniturePetCustomizationLogic.ts new file mode 100644 index 00000000..35f5d66d --- /dev/null +++ b/src/nitro/room/object/logic/furniture/FurniturePetCustomizationLogic.ts @@ -0,0 +1,6 @@ +import { FurnitureLogic } from './FurnitureLogic'; + +export class FurniturePetCustomizationLogic extends FurnitureLogic +{ + +} \ No newline at end of file diff --git a/src/nitro/room/object/logic/furniture/FurniturePresentLogic.ts b/src/nitro/room/object/logic/furniture/FurniturePresentLogic.ts new file mode 100644 index 00000000..80a72839 --- /dev/null +++ b/src/nitro/room/object/logic/furniture/FurniturePresentLogic.ts @@ -0,0 +1,114 @@ +import { IAssetData } from '../../../../../core/asset/interfaces'; +import { RoomSpriteMouseEvent } from '../../../../../room/events/RoomSpriteMouseEvent'; +import { RoomObjectUpdateMessage } from '../../../../../room/messages/RoomObjectUpdateMessage'; +import { IRoomGeometry } from '../../../../../room/utils/IRoomGeometry'; +import { MouseEventType } from '../../../../ui/MouseEventType'; +import { RoomObjectFurnitureActionEvent } from '../../../events/RoomObjectFurnitureActionEvent'; +import { RoomObjectWidgetRequestEvent } from '../../../events/RoomObjectWidgetRequestEvent'; +import { ObjectDataUpdateMessage } from '../../../messages/ObjectDataUpdateMessage'; +import { ObjectModelDataUpdateMessage } from '../../../messages/ObjectModelDataUpdateMessage'; +import { MapDataType } from '../../data/type/MapDataType'; +import { RoomObjectVariable } from '../../RoomObjectVariable'; +import { FurnitureLogic } from './FurnitureLogic'; + +export class FurniturePresentLogic extends FurnitureLogic +{ + private static MESSAGE: string = 'MESSAGE'; + private static PRODUCT_CODE: string = 'PRODUCT_CODE'; + private static EXTRA_PARAM: string = 'EXTRA_PARAM'; + private static PURCHASER_NAME: string = 'PURCHASER_NAME'; + private static PURCHASER_FIGURE: string = 'PURCHASER_FIGURE'; + + public getEventTypes(): string[] + { + const types = [ + RoomObjectWidgetRequestEvent.PRESENT + ]; + + return this.mergeTypes(super.getEventTypes(), types); + } + + public initialize(asset: IAssetData): void + { + super.initialize(asset); + + // particle system etc + } + + public processUpdateMessage(message: RoomObjectUpdateMessage): void + { + super.processUpdateMessage(message); + + if(message instanceof ObjectDataUpdateMessage) + { + message.data.writeRoomObjectModel(this.object.model); + + this.updateStuffData(); + } + + if(message instanceof ObjectModelDataUpdateMessage) + { + if(message.numberKey === RoomObjectVariable.FURNITURE_DISABLE_PICKING_ANIMATION) + { + this.object.model.setValue(RoomObjectVariable.FURNITURE_DISABLE_PICKING_ANIMATION, message.numberValue); + } + } + } + + private updateStuffData(): void + { + if(!this.object || !this.object.model) return; + + const stuffData = new MapDataType(); + + stuffData.initializeFromRoomObjectModel(this.object.model); + + const message = stuffData.getValue(FurniturePresentLogic.MESSAGE); + const data = this.object.model.getValue(RoomObjectVariable.FURNITURE_DATA); + + if(!message && (typeof data === 'string')) + { + this.object.model.setValue(RoomObjectVariable.FURNITURE_DATA, data.substr(1)); + } + else + { + this.object.model.setValue(RoomObjectVariable.FURNITURE_DATA, stuffData.getValue(FurniturePresentLogic.MESSAGE)); + } + + this.writeToModel(RoomObjectVariable.FURNITURE_TYPE_ID, stuffData.getValue(FurniturePresentLogic.PRODUCT_CODE)); + this.writeToModel(RoomObjectVariable.FURNITURE_PURCHASER_NAME, stuffData.getValue(FurniturePresentLogic.PURCHASER_NAME)); + this.writeToModel(RoomObjectVariable.FURNITURE_PURCHASER_FIGURE, stuffData.getValue(FurniturePresentLogic.PURCHASER_FIGURE)); + } + + private writeToModel(key: string, value: string): void + { + if(!value) return; + + this.object.model.setValue(key, value); + } + + public mouseEvent(event: RoomSpriteMouseEvent, geometry: IRoomGeometry): void + { + if(!event || !geometry || !this.object) return; + + switch(event.type) + { + case MouseEventType.ROLL_OVER: + this.eventDispatcher.dispatchEvent(new RoomObjectFurnitureActionEvent(RoomObjectFurnitureActionEvent.MOUSE_BUTTON, this.object)); + break; + case MouseEventType.ROLL_OUT: + this.eventDispatcher.dispatchEvent(new RoomObjectFurnitureActionEvent(RoomObjectFurnitureActionEvent.MOUSE_ARROW, this.object)); + break; + case MouseEventType.DOUBLE_CLICK: + this.useObject(); + return; + default: + super.mouseEvent(event, geometry); + } + } + + public useObject(): void + { + (this.object && this.eventDispatcher && this.eventDispatcher.dispatchEvent(new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.PRESENT, this.object))); + } +} diff --git a/src/nitro/room/object/logic/furniture/FurniturePurchaseableClothingLogic.ts b/src/nitro/room/object/logic/furniture/FurniturePurchaseableClothingLogic.ts new file mode 100644 index 00000000..a835f7b0 --- /dev/null +++ b/src/nitro/room/object/logic/furniture/FurniturePurchaseableClothingLogic.ts @@ -0,0 +1,20 @@ +import { RoomObjectWidgetRequestEvent } from '../../../events/RoomObjectWidgetRequestEvent'; +import { FurnitureMultiStateLogic } from './FurnitureMultiStateLogic'; + +export class FurniturePurchaseableClothingLogic extends FurnitureMultiStateLogic +{ + + public getEventTypes(): string[] + { + const types = [ + RoomObjectWidgetRequestEvent.PURCHASABLE_CLOTHING_CONFIRMATION_DIALOG, + ]; + + return this.mergeTypes(super.getEventTypes(), types); + } + + public useObject(): void + { + this.eventDispatcher.dispatchEvent(new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.PURCHASABLE_CLOTHING_CONFIRMATION_DIALOG, this.object)); + } +} \ No newline at end of file diff --git a/src/nitro/room/object/logic/furniture/FurniturePushableLogic.ts b/src/nitro/room/object/logic/furniture/FurniturePushableLogic.ts new file mode 100644 index 00000000..c95ac8c0 --- /dev/null +++ b/src/nitro/room/object/logic/furniture/FurniturePushableLogic.ts @@ -0,0 +1,6 @@ +import { FurnitureMultiStateLogic } from './FurnitureMultiStateLogic'; + +export class FurniturePushableLogic extends FurnitureMultiStateLogic +{ + +} \ No newline at end of file diff --git a/src/nitro/room/object/logic/furniture/FurnitureRoomBackgroundColorLogic.ts b/src/nitro/room/object/logic/furniture/FurnitureRoomBackgroundColorLogic.ts new file mode 100644 index 00000000..f33be885 --- /dev/null +++ b/src/nitro/room/object/logic/furniture/FurnitureRoomBackgroundColorLogic.ts @@ -0,0 +1,110 @@ +import { RoomSpriteMouseEvent } from '../../../../../room/events/RoomSpriteMouseEvent'; +import { RoomObjectUpdateMessage } from '../../../../../room/messages/RoomObjectUpdateMessage'; +import { IRoomGeometry } from '../../../../../room/utils/IRoomGeometry'; +import { MouseEventType } from '../../../../ui/MouseEventType'; +import { RoomObjectHSLColorEnableEvent } from '../../../events/RoomObjectHSLColorEnableEvent'; +import { RoomObjectWidgetRequestEvent } from '../../../events/RoomObjectWidgetRequestEvent'; +import { ObjectDataUpdateMessage } from '../../../messages/ObjectDataUpdateMessage'; +import { NumberDataType } from '../../data/type/NumberDataType'; +import { RoomObjectVariable } from '../../RoomObjectVariable'; +import { FurnitureMultiStateLogic } from './FurnitureMultiStateLogic'; + +export class FurnitureRoomBackgroundColorLogic extends FurnitureMultiStateLogic +{ + + private _roomColorUpdated: boolean; + + constructor() + { + super(); + + this._roomColorUpdated = false; + } + + public getEventTypes(): string[] + { + const types = [ + RoomObjectWidgetRequestEvent.BACKGROUND_COLOR, + RoomObjectHSLColorEnableEvent.ROOM_BACKGROUND_COLOR + ]; + + return this.mergeTypes(super.getEventTypes(), types); + } + + public dispose(): void + { + if(this._roomColorUpdated) + { + if(this.eventDispatcher && this.object) + { + const realRoomObject = this.object.model.getValue(RoomObjectVariable.FURNITURE_REAL_ROOM_OBJECT); + + if(realRoomObject === 1) + { + this.eventDispatcher.dispatchEvent(new RoomObjectHSLColorEnableEvent(RoomObjectHSLColorEnableEvent.ROOM_BACKGROUND_COLOR, this.object, false, 0, 0, 0)); + } + } + + this._roomColorUpdated = false; + } + + super.dispose(); + } + + public processUpdateMessage(message: RoomObjectUpdateMessage): void + { + super.processUpdateMessage(message); + + if(message instanceof ObjectDataUpdateMessage) + { + message.data.writeRoomObjectModel(this.object.model); + + const realRoomObject = this.object.model.getValue(RoomObjectVariable.FURNITURE_REAL_ROOM_OBJECT); + + if(realRoomObject === 1) this.processColorUpdate(); + } + } + + private processColorUpdate(): void + { + if(!this.object || !this.object.model) return; + + const numberData = new NumberDataType(); + + numberData.initializeFromRoomObjectModel(this.object.model); + + const state = numberData.getValue(0); + const hue = numberData.getValue(1); + const saturation = numberData.getValue(2); + const lightness = numberData.getValue(3); + + if((state > -1) && (hue > -1) && (saturation > -1) && (lightness > -1)) + { + this.object.model.setValue(RoomObjectVariable.FURNITURE_ROOM_BACKGROUND_COLOR_HUE, hue); + this.object.model.setValue(RoomObjectVariable.FURNITURE_ROOM_BACKGROUND_COLOR_SATURATION, saturation); + this.object.model.setValue(RoomObjectVariable.FURNITURE_ROOM_BACKGROUND_COLOR_LIGHTNESS, lightness); + + this.object.setState(state, 0); + + if(this.eventDispatcher) + { + this.eventDispatcher.dispatchEvent(new RoomObjectHSLColorEnableEvent(RoomObjectHSLColorEnableEvent.ROOM_BACKGROUND_COLOR, this.object, (state === 1), hue, saturation, lightness)); + } + + this._roomColorUpdated = true; + } + } + + public mouseEvent(event: RoomSpriteMouseEvent, geometry: IRoomGeometry): void + { + if(!event || !geometry || !this.object) return; + switch(event.type) + { + case MouseEventType.DOUBLE_CLICK: + (this.eventDispatcher && this.eventDispatcher.dispatchEvent(new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.BACKGROUND_COLOR, this.object))); + return; + default: + super.mouseEvent(event, geometry); + } + } +} diff --git a/src/nitro/room/object/logic/furniture/FurnitureRoomBackgroundLogic.ts b/src/nitro/room/object/logic/furniture/FurnitureRoomBackgroundLogic.ts new file mode 100644 index 00000000..da18c927 --- /dev/null +++ b/src/nitro/room/object/logic/furniture/FurnitureRoomBackgroundLogic.ts @@ -0,0 +1,10 @@ +import { IRoomObjectModel } from '../../../../../room/object/IRoomObjectModel'; +import { FurnitureRoomBrandingLogic } from './FurnitureRoomBrandingLogic'; + +export class FurnitureRoomBackgroundLogic extends FurnitureRoomBrandingLogic +{ + protected getAdClickUrl(model: IRoomObjectModel): string + { + return null; + } +} \ No newline at end of file diff --git a/src/nitro/room/object/logic/furniture/FurnitureRoomBillboardLogic.ts b/src/nitro/room/object/logic/furniture/FurnitureRoomBillboardLogic.ts new file mode 100644 index 00000000..0c1aa11b --- /dev/null +++ b/src/nitro/room/object/logic/furniture/FurnitureRoomBillboardLogic.ts @@ -0,0 +1,18 @@ +import { IRoomObjectModel } from '../../../../../room/object/IRoomObjectModel'; +import { RoomObjectVariable } from '../../RoomObjectVariable'; +import { FurnitureRoomBrandingLogic } from './FurnitureRoomBrandingLogic'; + +export class FurnitureRoomBillboardLogic extends FurnitureRoomBrandingLogic +{ + constructor() + { + super(); + + this._hasClickUrl = true; + } + + protected getAdClickUrl(model: IRoomObjectModel): string + { + return model.getValue(RoomObjectVariable.FURNITURE_BRANDING_URL); + } +} \ No newline at end of file diff --git a/src/nitro/room/object/logic/furniture/FurnitureRoomBrandingLogic.ts b/src/nitro/room/object/logic/furniture/FurnitureRoomBrandingLogic.ts new file mode 100644 index 00000000..4fa661a5 --- /dev/null +++ b/src/nitro/room/object/logic/furniture/FurnitureRoomBrandingLogic.ts @@ -0,0 +1,145 @@ +import { RoomObjectUpdateMessage } from '../../../../../room/messages/RoomObjectUpdateMessage'; +import { Nitro } from '../../../../Nitro'; +import { RoomWidgetEnumItemExtradataParameter } from '../../../../ui/widget/enums/RoomWidgetEnumItemExtradataParameter'; +import { ObjectAdUpdateMessage } from '../../../messages/ObjectAdUpdateMessage'; +import { ObjectDataUpdateMessage } from '../../../messages/ObjectDataUpdateMessage'; +import { MapDataType } from '../../data/type/MapDataType'; +import { RoomObjectVariable } from '../../RoomObjectVariable'; +import { FurnitureLogic } from './FurnitureLogic'; + +export class FurnitureRoomBrandingLogic extends FurnitureLogic +{ + public static STATE: string = 'state'; + public static IMAGEURL_KEY: string = 'imageUrl'; + public static CLICKURL_KEY: string = 'clickUrl'; + public static OFFSETX_KEY: string = 'offsetX'; + public static OFFSETY_KEY: string = 'offsetY'; + public static OFFSETZ_KEY: string = 'offsetZ'; + + protected _hasClickUrl: boolean; + + constructor() + { + super(); + + this._hasClickUrl = false; + } + + public processUpdateMessage(message: RoomObjectUpdateMessage): void + { + super.processUpdateMessage(message); + + if(message instanceof ObjectDataUpdateMessage) this.processAdDataUpdateMessage(message); + + if(message instanceof ObjectAdUpdateMessage) this.processAdUpdate(message); + } + + private processAdDataUpdateMessage(message: ObjectDataUpdateMessage): void + { + if(!message) return; + + const objectData = new MapDataType(); + + objectData.initializeFromRoomObjectModel(this.object.model); + + const state = parseInt(objectData.getValue(FurnitureRoomBrandingLogic.STATE)); + + if(!isNaN(state) && (this.object.getState(0) !== state)) this.object.setState(state, 0); + + const imageUrl = objectData.getValue(FurnitureRoomBrandingLogic.IMAGEURL_KEY); + const existingUrl = this.object.model.getValue(RoomObjectVariable.FURNITURE_BRANDING_IMAGE_URL); + + if(!existingUrl || (existingUrl !== imageUrl)) + { + this.object.model.setValue(RoomObjectVariable.FURNITURE_BRANDING_IMAGE_URL, imageUrl); + this.object.model.setValue(RoomObjectVariable.FURNITURE_BRANDING_IMAGE_STATUS, 0); + + this.downloadBackground(); + } + + const clickUrl = objectData.getValue(FurnitureRoomBrandingLogic.CLICKURL_KEY); + + if(clickUrl) + { + const existingUrl = this.object.model.getValue(RoomObjectVariable.FURNITURE_BRANDING_URL); + + if(!existingUrl || existingUrl !== clickUrl) + { + if(this.object.model) this.object.model.setValue(RoomObjectVariable.FURNITURE_BRANDING_URL, clickUrl); + } + } + + const offsetX = parseInt(objectData.getValue(FurnitureRoomBrandingLogic.OFFSETX_KEY)); + const offsetY = parseInt(objectData.getValue(FurnitureRoomBrandingLogic.OFFSETY_KEY)); + const offsetZ = parseInt(objectData.getValue(FurnitureRoomBrandingLogic.OFFSETZ_KEY)); + + if(!isNaN(offsetX)) this.object.model.setValue(RoomObjectVariable.FURNITURE_BRANDING_OFFSET_X, offsetX); + if(!isNaN(offsetY)) this.object.model.setValue(RoomObjectVariable.FURNITURE_BRANDING_OFFSET_Y, offsetY); + if(!isNaN(offsetZ)) this.object.model.setValue(RoomObjectVariable.FURNITURE_BRANDING_OFFSET_Z, offsetZ); + + let options = (((FurnitureRoomBrandingLogic.IMAGEURL_KEY + '=') + ((imageUrl !== null) ? imageUrl : '')) + '\t'); + + if(this._hasClickUrl) + { + options = (options + (((FurnitureRoomBrandingLogic.CLICKURL_KEY + '=') + ((clickUrl !== null) ? clickUrl : '')) + '\t')); + } + + options = (options + (((FurnitureRoomBrandingLogic.OFFSETX_KEY + '=') + offsetX) + '\t')); + options = (options + (((FurnitureRoomBrandingLogic.OFFSETY_KEY + '=') + offsetY) + '\t')); + options = (options + (((FurnitureRoomBrandingLogic.OFFSETZ_KEY + '=') + offsetZ) + '\t')); + + this.object.model.setValue(RoomWidgetEnumItemExtradataParameter.INFOSTAND_EXTRA_PARAM, (RoomWidgetEnumItemExtradataParameter.BRANDING_OPTIONS + options)); + } + + private processAdUpdate(message: ObjectAdUpdateMessage): void + { + if(!message || !this.object) return; + + switch(message.type) + { + case ObjectAdUpdateMessage.IMAGE_LOADED: + this.object.model.setValue(RoomObjectVariable.FURNITURE_BRANDING_IMAGE_STATUS, 1); + break; + case ObjectAdUpdateMessage.IMAGE_LOADING_FAILED: + this.object.model.setValue(RoomObjectVariable.FURNITURE_BRANDING_IMAGE_STATUS, -1); + break; + } + } + + private downloadBackground(): void + { + const model = this.object && this.object.model; + + if(!model) return; + + const imageUrl = model.getValue(RoomObjectVariable.FURNITURE_BRANDING_IMAGE_URL); + const imageStatus = model.getValue(RoomObjectVariable.FURNITURE_BRANDING_IMAGE_STATUS); + + if(!imageUrl || (imageUrl === '') || (imageStatus === 1)) return; + + const asset = Nitro.instance.core && Nitro.instance.core.asset; + + if(!asset) return; + + const texture = asset.getTexture(imageUrl); + + if(!texture) + { + asset.downloadAsset(imageUrl, (flag: boolean) => + { + if(flag) + { + this.processUpdateMessage(new ObjectAdUpdateMessage(ObjectAdUpdateMessage.IMAGE_LOADED)); + } + else + { + this.processUpdateMessage(new ObjectAdUpdateMessage(ObjectAdUpdateMessage.IMAGE_LOADING_FAILED)); + } + }); + + return; + } + + this.processUpdateMessage(new ObjectAdUpdateMessage(ObjectAdUpdateMessage.IMAGE_LOADED)); + } +} diff --git a/src/nitro/room/object/logic/furniture/FurnitureRoomDimmerLogic.ts b/src/nitro/room/object/logic/furniture/FurnitureRoomDimmerLogic.ts new file mode 100644 index 00000000..35d850fd --- /dev/null +++ b/src/nitro/room/object/logic/furniture/FurnitureRoomDimmerLogic.ts @@ -0,0 +1,140 @@ +import { RoomObjectUpdateMessage } from '../../../../../room/messages/RoomObjectUpdateMessage'; +import { RoomObjectDimmerStateUpdateEvent } from '../../../events/RoomObjectDimmerStateUpdateEvent'; +import { RoomObjectWidgetRequestEvent } from '../../../events/RoomObjectWidgetRequestEvent'; +import { ObjectDataUpdateMessage } from '../../../messages/ObjectDataUpdateMessage'; +import { RoomObjectVariable } from '../../RoomObjectVariable'; +import { FurnitureLogic } from './FurnitureLogic'; + +export class FurnitureRoomDimmerLogic extends FurnitureLogic +{ + private _roomColorUpdated: boolean; + + constructor() + { + super(); + + this._roomColorUpdated = false; + } + + public getEventTypes(): string[] + { + const types = [ + RoomObjectWidgetRequestEvent.DIMMER, + RoomObjectWidgetRequestEvent.WIDGET_REMOVE_DIMMER, + RoomObjectDimmerStateUpdateEvent.DIMMER_STATE + ]; + + return this.mergeTypes(super.getEventTypes(), types); + } + + public dispose(): void + { + if(this._roomColorUpdated) + { + if(this.eventDispatcher && this.object) + { + const realRoomObject = this.object.model.getValue(RoomObjectVariable.FURNITURE_REAL_ROOM_OBJECT); + + if(realRoomObject === 1) + { + this.eventDispatcher.dispatchEvent(new RoomObjectDimmerStateUpdateEvent(this.object, 0, 1, 1, 0xFFFFFF, 0xFF)); + this.eventDispatcher.dispatchEvent(new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.WIDGET_REMOVE_DIMMER, this.object)); + } + + this._roomColorUpdated = false; + } + } + + super.dispose(); + } + + public processUpdateMessage(message: RoomObjectUpdateMessage): void + { + if(message instanceof ObjectDataUpdateMessage) + { + if(message.data) + { + const extra = message.data.getLegacyString(); + + const realRoomObject = this.object.model.getValue(RoomObjectVariable.FURNITURE_REAL_ROOM_OBJECT); + + if(realRoomObject === 1) this.processDimmerData(extra); + + super.processUpdateMessage(new ObjectDataUpdateMessage(this.getStateFromDimmerData(extra), message.data)); + } + + return; + } + + super.processUpdateMessage(message); + } + + private getStateFromDimmerData(data: string): number + { + if(!data) return 0; + + const parts = data.split(','); + + if(parts.length >= 5) return (parseInt(parts[0]) - 1); + + return 0; + } + + private processDimmerData(data: string): void + { + if(!data) return; + + const parts = data.split(','); + + if(parts.length >= 5) + { + const state = this.getStateFromDimmerData(data); + const presetId = parseInt(parts[1]); + const effectId = parseInt(parts[2]); + const color = parts[3]; + + let colorCode = parseInt(color.substr(1), 16); + let brightness = parseInt(parts[4]); + + if(!state) + { + colorCode = 0xFFFFFF; + brightness = 0xFF; + } + + if(this.eventDispatcher && this.object) + { + this.eventDispatcher.dispatchEvent(new RoomObjectDimmerStateUpdateEvent(this.object, state, presetId, effectId, colorCode, brightness)); + + this._roomColorUpdated = true; + } + } + } + + public useObject(): void + { + this.eventDispatcher.dispatchEvent(new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.DIMMER, this.object)); + } + + public update(time: number): void + { + super.update(time); + + if(this.object && this.object.model) + { + const realRoomObject = this.object.model.getValue(RoomObjectVariable.FURNITURE_REAL_ROOM_OBJECT); + + if(realRoomObject === 1) + { + const data = this.object.model.getValue(RoomObjectVariable.FURNITURE_DATA); + + if(data && data.length > 0) + { + this.object.model.setValue(RoomObjectVariable.FURNITURE_DATA, ''); + + this.processDimmerData(data); + } + } + } + } +} \ No newline at end of file diff --git a/src/nitro/room/object/logic/furniture/FurnitureScoreLogic.ts b/src/nitro/room/object/logic/furniture/FurnitureScoreLogic.ts new file mode 100644 index 00000000..99e53692 --- /dev/null +++ b/src/nitro/room/object/logic/furniture/FurnitureScoreLogic.ts @@ -0,0 +1,71 @@ +import { RoomObjectUpdateMessage } from '../../../../../room/messages/RoomObjectUpdateMessage'; +import { Nitro } from '../../../../Nitro'; +import { ObjectDataUpdateMessage } from '../../../messages/ObjectDataUpdateMessage'; +import { FurnitureLogic } from './FurnitureLogic'; + +export class FurnitureScoreLogic extends FurnitureLogic +{ + private static _Str_3536: number = 50; + private static _Str_5967: number = 3000; + + private _score: number; + private _scoreIncreaser: number; + private _scoreTimer: number; + + constructor() + { + super(); + + this._score = 0; + this._scoreIncreaser = 50; + this._scoreTimer = 0; + } + + public processUpdateMessage(message: RoomObjectUpdateMessage): void + { + if(message instanceof ObjectDataUpdateMessage) return this.updateScore(message.state); + + super.processUpdateMessage(message); + } + + private updateScore(count: number): void + { + this._score = count; + + const currentScore = this.object.getState(0); + + if(this._score !== currentScore) + { + let difference = (this._score - currentScore); + + if(difference < 0) difference = -(difference); + + if((difference * FurnitureScoreLogic._Str_3536) > FurnitureScoreLogic._Str_5967) this._scoreIncreaser = (FurnitureScoreLogic._Str_5967 / difference); + else this._scoreIncreaser = FurnitureScoreLogic._Str_3536; + + this._scoreTimer = Nitro.instance.time; + } + } + + public update(time: number): void + { + super.update(time); + + const currentScore = this.object.getState(0); + + if((currentScore !== this._score) && (time >= (this._scoreTimer + this._scoreIncreaser))) + { + const _local_3 = (time - this._scoreTimer); + let _local_4 = (_local_3 / this._scoreIncreaser); + let _local_5 = 1; + + if(this._score < currentScore) _local_5 = -1; + + if(_local_4 > (_local_5 * (this._score - currentScore))) _local_4 = (_local_5 * (this._score - currentScore)); + + this.object.setState((currentScore + (_local_5 * _local_4)), 0); + + this._scoreTimer = (time - (_local_3 - (_local_4 * this._scoreIncreaser))); + } + } +} diff --git a/src/nitro/room/object/logic/furniture/FurnitureSoundBlockLogic.ts b/src/nitro/room/object/logic/furniture/FurnitureSoundBlockLogic.ts new file mode 100644 index 00000000..6a719c88 --- /dev/null +++ b/src/nitro/room/object/logic/furniture/FurnitureSoundBlockLogic.ts @@ -0,0 +1,131 @@ +import { IAssetData } from '../../../../../core/asset/interfaces'; +import { RoomObjectUpdateMessage } from '../../../../../room/messages/RoomObjectUpdateMessage'; +import { RoomObjectSamplePlaybackEvent } from '../../../events/RoomObjectSamplePlaybackEvent'; +import { ObjectDataUpdateMessage } from '../../../messages/ObjectDataUpdateMessage'; +import { RoomObjectVariable } from '../../RoomObjectVariable'; +import { FurnitureMultiStateLogic } from './FurnitureMultiStateLogic'; + +export class FurnitureSoundBlockLogic extends FurnitureMultiStateLogic +{ + private static HIGHEST_SEMITONE: number = 12; + private static LOWEST_SEMITONE: number = -12; + private static STATE_UNINITIALIZED: number = -1; + + private _state: number; + private _sampleId: number; + private _noPitch: boolean; + private _lastLocZ: number; + + constructor() + { + super(); + + this._state = -1; + this._sampleId = -1; + this._noPitch = false; + this._lastLocZ = 0; + } + + public getEventTypes(): string[] + { + const types = [ + RoomObjectSamplePlaybackEvent.ROOM_OBJECT_INITIALIZED, + RoomObjectSamplePlaybackEvent.ROOM_OBJECT_DISPOSED, + RoomObjectSamplePlaybackEvent.PLAY_SAMPLE, + RoomObjectSamplePlaybackEvent.CHANGE_PITCH + ]; + + return this.mergeTypes(super.getEventTypes(), types); + } + + public initialize(asset: IAssetData): void + { + super.initialize(asset); + + if(!asset.soundSample) return; + + this._sampleId = asset.soundSample; + this.updateModel(); + } + + public dispose(): void + { + super.dispose(); + + if(this._state !== FurnitureSoundBlockLogic.STATE_UNINITIALIZED) + { + this.eventDispatcher.dispatchEvent(new RoomObjectSamplePlaybackEvent(RoomObjectSamplePlaybackEvent.ROOM_OBJECT_DISPOSED, this.object, this._sampleId)); + } + } + + public processUpdateMessage(message: RoomObjectUpdateMessage): void + { + super.processUpdateMessage(message); + + if(message instanceof ObjectDataUpdateMessage) this.updateSoundBlockMessage(message); + } + + private updateSoundBlockMessage(message: ObjectDataUpdateMessage): void + { + if(!message) return; + + const model = this.object && this.object.model; + const location = this.object && this.object.location; + + if(!model || !location) return; + + if(this._state === FurnitureSoundBlockLogic.STATE_UNINITIALIZED && model.getValue(RoomObjectVariable.FURNITURE_REAL_ROOM_OBJECT) === 1) + { + this._lastLocZ = location.z; + this.eventDispatcher.dispatchEvent(new RoomObjectSamplePlaybackEvent(RoomObjectSamplePlaybackEvent.ROOM_OBJECT_INITIALIZED, this.object, this._sampleId, this._Str_17428(location.z))); + } + + if(this._state !== FurnitureSoundBlockLogic.STATE_UNINITIALIZED && model.getValue(RoomObjectVariable.FURNITURE_REAL_ROOM_OBJECT) === 1) + { + if(this._lastLocZ !== location.z) + { + this._lastLocZ = location.z; + this.eventDispatcher.dispatchEvent(new RoomObjectSamplePlaybackEvent(RoomObjectSamplePlaybackEvent.CHANGE_PITCH, this.object, this._sampleId, this._Str_17428(location.z))); + } + + } + + if(this._state !== FurnitureSoundBlockLogic.STATE_UNINITIALIZED && message.state !== this._state) + { + this._Str_18183(location.z); + } + + this._state = message.state; + } + + protected updateModel(): boolean + { + const model = this.object && this.object.model; + + if(!model) return false; + + model.setValue(RoomObjectVariable.FURNITURE_SOUNDBLOCK_RELATIVE_ANIMATION_SPEED, 1); + } + + private _Str_18183(k: number): void + { + const model = this.object && this.object.model; + + if(!model) return; + + const _local_2: number = this._Str_17428(k); + + model.setValue(RoomObjectVariable.FURNITURE_SOUNDBLOCK_RELATIVE_ANIMATION_SPEED, _local_2); + this.eventDispatcher.dispatchEvent(new RoomObjectSamplePlaybackEvent(RoomObjectSamplePlaybackEvent.PLAY_SAMPLE, this.object, this._sampleId, _local_2)); + } + + private _Str_17428(k: number): number + { + let _local_2: number = (k * 2); + if(_local_2 > FurnitureSoundBlockLogic.HIGHEST_SEMITONE) + { + _local_2 = Math.min(0, (FurnitureSoundBlockLogic.LOWEST_SEMITONE + ((_local_2 - FurnitureSoundBlockLogic.HIGHEST_SEMITONE) - 1))); + } + return (this._noPitch) ? 1 : Math.pow(2, (_local_2 / 12)); + } +} diff --git a/src/nitro/room/object/logic/furniture/FurnitureStickieLogic.ts b/src/nitro/room/object/logic/furniture/FurnitureStickieLogic.ts new file mode 100644 index 00000000..eea8fe3d --- /dev/null +++ b/src/nitro/room/object/logic/furniture/FurnitureStickieLogic.ts @@ -0,0 +1,78 @@ +import { IAssetData } from '../../../../../core/asset/interfaces'; +import { RoomSpriteMouseEvent } from '../../../../../room/events/RoomSpriteMouseEvent'; +import { RoomObjectUpdateMessage } from '../../../../../room/messages/RoomObjectUpdateMessage'; +import { IRoomGeometry } from '../../../../../room/utils/IRoomGeometry'; +import { MouseEventType } from '../../../../ui/MouseEventType'; +import { RoomObjectFurnitureActionEvent } from '../../../events/RoomObjectFurnitureActionEvent'; +import { RoomObjectWidgetRequestEvent } from '../../../events/RoomObjectWidgetRequestEvent'; +import { ObjectItemDataUpdateMessage } from '../../../messages/ObjectItemDataUpdateMessage'; +import { RoomObjectVariable } from '../../RoomObjectVariable'; +import { FurnitureLogic } from './FurnitureLogic'; + +export class FurnitureStickieLogic extends FurnitureLogic +{ + private static STICKIE_COLORS: string[] = [ '9CCEFF', 'FF9CFF', '9CFF9C', 'FFFF33' ]; + + public getEventTypes(): string[] + { + const types = [ + RoomObjectWidgetRequestEvent.STICKIE, + RoomObjectFurnitureActionEvent.STICKIE + ]; + + return this.mergeTypes(super.getEventTypes(), types); + } + + public initialize(asset: IAssetData): void + { + super.initialize(asset); + + this.updateColor(); + + if(this.object) this.object.model.setValue(RoomObjectVariable.FURNITURE_IS_STICKIE, ''); + } + + public processUpdateMessage(message: RoomObjectUpdateMessage): void + { + super.processUpdateMessage(message); + + if(message instanceof ObjectItemDataUpdateMessage) + { + this.eventDispatcher && this.eventDispatcher.dispatchEvent(new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.STICKIE, this.object)); + } + + this.updateColor(); + } + + protected updateColor(): void + { + if(!this.object) return; + + const furnitureData = this.object.model.getValue(RoomObjectVariable.FURNITURE_DATA); + + let colorIndex = FurnitureStickieLogic.STICKIE_COLORS.indexOf(furnitureData); + + if(colorIndex < 0) colorIndex = 3; + + this.object.model.setValue(RoomObjectVariable.FURNITURE_COLOR, (colorIndex + 1)); + } + + public mouseEvent(event: RoomSpriteMouseEvent, geometry: IRoomGeometry): void + { + if(!event || !geometry || !this.object) return; + + switch(event.type) + { + case MouseEventType.DOUBLE_CLICK: + this.useObject(); + return; + default: + super.mouseEvent(event, geometry); + } + } + + public useObject(): void + { + (this.object && this.eventDispatcher && this.eventDispatcher.dispatchEvent(new RoomObjectFurnitureActionEvent(RoomObjectFurnitureActionEvent.STICKIE, this.object))); + } +} \ No newline at end of file diff --git a/src/nitro/room/object/logic/furniture/FurnitureTrophyLogic.ts b/src/nitro/room/object/logic/furniture/FurnitureTrophyLogic.ts new file mode 100644 index 00000000..726302dd --- /dev/null +++ b/src/nitro/room/object/logic/furniture/FurnitureTrophyLogic.ts @@ -0,0 +1,36 @@ +import { RoomSpriteMouseEvent } from '../../../../../room/events/RoomSpriteMouseEvent'; +import { IRoomGeometry } from '../../../../../room/utils/IRoomGeometry'; +import { MouseEventType } from '../../../../ui/MouseEventType'; +import { RoomObjectWidgetRequestEvent } from '../../../events/RoomObjectWidgetRequestEvent'; +import { FurnitureLogic } from './FurnitureLogic'; + +export class FurnitureTrophyLogic extends FurnitureLogic +{ + public getEventTypes(): string[] + { + const types = [ RoomObjectWidgetRequestEvent.TROPHY ]; + + return this.mergeTypes(super.getEventTypes(), types); + } + + public mouseEvent(event: RoomSpriteMouseEvent, geometry: IRoomGeometry): void + { + if(!event || !geometry || !this.object) return; + + switch(event.type) + { + case MouseEventType.DOUBLE_CLICK: + this.useObject(); + return; + } + + super.mouseEvent(event, geometry); + } + + public useObject(): void + { + if(!this.eventDispatcher || !this.object) return; + + this.eventDispatcher.dispatchEvent(new RoomObjectWidgetRequestEvent(RoomObjectWidgetRequestEvent.TROPHY, this.object)); + } +} \ No newline at end of file diff --git a/src/nitro/room/object/logic/furniture/FurnitureVoteCounterLogic.ts b/src/nitro/room/object/logic/furniture/FurnitureVoteCounterLogic.ts new file mode 100644 index 00000000..f3ade08a --- /dev/null +++ b/src/nitro/room/object/logic/furniture/FurnitureVoteCounterLogic.ts @@ -0,0 +1,97 @@ +import { RoomObjectUpdateMessage } from '../../../../../room/messages/RoomObjectUpdateMessage'; +import { Nitro } from '../../../../Nitro'; +import { ObjectDataUpdateMessage } from '../../../messages/ObjectDataUpdateMessage'; +import { VoteDataType } from '../../data/type/VoteDataType'; +import { RoomObjectVariable } from '../../RoomObjectVariable'; +import { FurnitureMultiStateLogic } from './FurnitureMultiStateLogic'; + +export class FurnitureVoteCounterLogic extends FurnitureMultiStateLogic +{ + private static _Str_3536: number = 33; + private static _Str_5967: number = 1000; + + private _total: number; + private _lastUpdate: number; + private _interval: number; + + constructor() + { + super(); + + this._total = 0; + this._lastUpdate = 0; + this._interval = 33; + } + + public processUpdateMessage(message: RoomObjectUpdateMessage): void + { + super.processUpdateMessage(message); + + if(message instanceof ObjectDataUpdateMessage) + { + const stuffData = (message.data as VoteDataType); + + if(!stuffData) return; + + this._Str_24990(stuffData.result); + } + } + + private _Str_24990(k: number): void + { + this._total = k; + + if(!this._lastUpdate) + { + this.object.model.setValue(RoomObjectVariable.FURNITURE_VOTE_COUNTER_COUNT, k); + + this._lastUpdate = Nitro.instance.time; + + return; + } + + if(this._total !== this._Str_8221) + { + const difference = Math.abs((this._total - this._Str_8221)); + + if((difference * FurnitureVoteCounterLogic._Str_3536) > FurnitureVoteCounterLogic._Str_5967) + { + this._interval = (FurnitureVoteCounterLogic._Str_5967 / difference); + } + else + { + this._interval = FurnitureVoteCounterLogic._Str_3536; + } + + this._lastUpdate = Nitro.instance.time; + } + } + + public update(time: number): void + { + super.update(time); + + if(this.object) + { + if((this._Str_8221 !== this._total) && (time >= (this._lastUpdate + this._interval))) + { + const _local_2 = (time - this._lastUpdate); + let _local_3 = (_local_2 / this._interval); + let _local_4 = 1; + + if(this._total < this._Str_8221) _local_4 = -1; + + if(_local_3 > (_local_4 * (this._total - this._Str_8221))) _local_3 = (_local_4 * (this._total - this._Str_8221)); + + this.object.model.setValue(RoomObjectVariable.FURNITURE_VOTE_COUNTER_COUNT, (this._Str_8221 + (_local_4 * _local_3))); + + this._lastUpdate = (time - (_local_2 - (_local_3 * this._interval))); + } + } + } + + private get _Str_8221(): number + { + return this.object.model.getValue(RoomObjectVariable.FURNITURE_VOTE_COUNTER_COUNT); + } +} diff --git a/src/nitro/room/object/logic/furniture/FurnitureVoteMajorityLogic.ts b/src/nitro/room/object/logic/furniture/FurnitureVoteMajorityLogic.ts new file mode 100644 index 00000000..65cc217c --- /dev/null +++ b/src/nitro/room/object/logic/furniture/FurnitureVoteMajorityLogic.ts @@ -0,0 +1,22 @@ +import { RoomObjectUpdateMessage } from '../../../../../room/messages/RoomObjectUpdateMessage'; +import { ObjectDataUpdateMessage } from '../../../messages/ObjectDataUpdateMessage'; +import { VoteDataType } from '../../data/type/VoteDataType'; +import { RoomObjectVariable } from '../../RoomObjectVariable'; +import { FurnitureMultiStateLogic } from './FurnitureMultiStateLogic'; + +export class FurnitureVoteMajorityLogic extends FurnitureMultiStateLogic +{ + public processUpdateMessage(message: RoomObjectUpdateMessage): void + { + super.processUpdateMessage(message); + + if(!this.object) return; + + if(message instanceof ObjectDataUpdateMessage) + { + const data = message.data; + + if(data instanceof VoteDataType) this.object.model.setValue(RoomObjectVariable.FURNITURE_VOTE_MAJORITY_RESULT, data.result); + } + } +} \ No newline at end of file diff --git a/src/nitro/room/object/logic/furniture/FurnitureWindowLogic.ts b/src/nitro/room/object/logic/furniture/FurnitureWindowLogic.ts new file mode 100644 index 00000000..093fdfbc --- /dev/null +++ b/src/nitro/room/object/logic/furniture/FurnitureWindowLogic.ts @@ -0,0 +1,18 @@ +import { IAssetData } from '../../../../../core/asset/interfaces'; +import { RoomObjectVariable } from '../../RoomObjectVariable'; +import { FurnitureMultiStateLogic } from './FurnitureMultiStateLogic'; + +export class FurnitureWindowLogic extends FurnitureMultiStateLogic +{ + public initialize(asset: IAssetData): void + { + super.initialize(asset); + + let maskType = ''; + + if(asset.maskType && (asset.maskType !== '') && (asset.maskType.length > 0)) maskType = asset.maskType; + + this.object.model.setValue(RoomObjectVariable.FURNITURE_USES_PLANE_MASK, 0); + this.object.model.setValue(RoomObjectVariable.FURNITURE_PLANE_MASK_TYPE, maskType); + } +} \ No newline at end of file diff --git a/src/nitro/room/object/logic/furniture/FurnitureYoutubeLogic.ts b/src/nitro/room/object/logic/furniture/FurnitureYoutubeLogic.ts new file mode 100644 index 00000000..ef007738 --- /dev/null +++ b/src/nitro/room/object/logic/furniture/FurnitureYoutubeLogic.ts @@ -0,0 +1,31 @@ +import { RoomWidgetEnum } from '../../../../ui/widget/enums/RoomWidgetEnum'; +import { RoomObjectDataRequestEvent } from '../../../events/RoomObjectDataRequestEvent'; +import { RoomObjectVariable } from '../../RoomObjectVariable'; +import { FurnitureLogic } from './FurnitureLogic'; + +export class FurnitureYoutubeLogic extends FurnitureLogic +{ + public getEventTypes(): string[] + { + const types = [ + RoomObjectDataRequestEvent.RODRE_URL_PREFIX + ]; + + return this.mergeTypes(super.getEventTypes(), types); + } + + public update(time: number): void + { + super.update(time); + + if(!this.object.model.getValue(RoomObjectVariable.SESSION_URL_PREFIX)) + { + this.eventDispatcher.dispatchEvent(new RoomObjectDataRequestEvent(RoomObjectDataRequestEvent.RODRE_URL_PREFIX, this.object)); + } + } + + public get widget(): string + { + return RoomWidgetEnum.YOUTUBE; + } +} diff --git a/src/nitro/room/object/logic/pet/PetLogic.ts b/src/nitro/room/object/logic/pet/PetLogic.ts new file mode 100644 index 00000000..e14580c0 --- /dev/null +++ b/src/nitro/room/object/logic/pet/PetLogic.ts @@ -0,0 +1,242 @@ +import { IAssetData } from '../../../../../core/asset/interfaces'; +import { RoomObjectMouseEvent } from '../../../../../room/events/RoomObjectMouseEvent'; +import { RoomSpriteMouseEvent } from '../../../../../room/events/RoomSpriteMouseEvent'; +import { RoomObjectUpdateMessage } from '../../../../../room/messages/RoomObjectUpdateMessage'; +import { IRoomObjectModel } from '../../../../../room/object/IRoomObjectModel'; +import { IRoomGeometry } from '../../../../../room/utils/IRoomGeometry'; +import { Vector3d } from '../../../../../room/utils/Vector3d'; +import { PetFigureData } from '../../../../avatar/pets/PetFigureData'; +import { PetType } from '../../../../avatar/pets/PetType'; +import { MouseEventType } from '../../../../ui/MouseEventType'; +import { RoomObjectMoveEvent } from '../../../events/RoomObjectMoveEvent'; +import { ObjectAvatarChatUpdateMessage } from '../../../messages/ObjectAvatarChatUpdateMessage'; +import { ObjectAvatarFigureUpdateMessage } from '../../../messages/ObjectAvatarFigureUpdateMessage'; +import { ObjectAvatarPetGestureUpdateMessage } from '../../../messages/ObjectAvatarPetGestureUpdateMessage'; +import { ObjectAvatarPostureUpdateMessage } from '../../../messages/ObjectAvatarPostureUpdateMessage'; +import { ObjectAvatarSelectedMessage } from '../../../messages/ObjectAvatarSelectedMessage'; +import { ObjectAvatarSleepUpdateMessage } from '../../../messages/ObjectAvatarSleepUpdateMessage'; +import { ObjectAvatarUpdateMessage } from '../../../messages/ObjectAvatarUpdateMessage'; +import { RoomObjectVariable } from '../../RoomObjectVariable'; +import { MovingObjectLogic } from '../MovingObjectLogic'; + +export class PetLogic extends MovingObjectLogic +{ + private _selected: boolean; + private _reportedLocation: Vector3d; + private _postureIndex: number; + private _gestureIndex: number; + private _headDirectionDelta: number; + private _directions: number[]; + + private _talkingEndTimestamp: number; + private _gestureEndTimestamp: number; + private _expressionEndTimestamp: number; + + constructor() + { + super(); + + this._selected = false; + this._reportedLocation = null; + this._postureIndex = 0; + this._gestureIndex = 0; + this._headDirectionDelta = 0; + this._directions = []; + + this._talkingEndTimestamp = 0; + this._gestureEndTimestamp = 0; + this._expressionEndTimestamp = 0; + } + + public getEventTypes(): string[] + { + const types = [ RoomObjectMouseEvent.CLICK, RoomObjectMoveEvent.POSITION_CHANGED ]; + + return this.mergeTypes(super.getEventTypes(), types); + } + + public initialize(asset: IAssetData): void + { + if(!asset) return; + + const model = this.object && this.object.model; + + if(!model) return; + + const directions = asset.directions; + + if(directions && directions.length) + { + for(const direction of directions) this._directions.push(direction); + + this._directions.sort((a, b) => + { + return a - b; + }); + } + + model.setValue(RoomObjectVariable.PET_ALLOWED_DIRECTIONS, this._directions); + } + + public dispose(): void + { + if(this._selected && this.object) + { + if(this.eventDispatcher) this.eventDispatcher.dispatchEvent(new RoomObjectMoveEvent(RoomObjectMoveEvent.OBJECT_REMOVED, this.object)); + } + + this._directions = null; + this._reportedLocation = null; + } + + public update(totalTimeRunning: number): void + { + super.update(totalTimeRunning); + + if(this._selected && this.object) + { + if(this.eventDispatcher) + { + const location = this.object.getLocation(); + + if(((!this._reportedLocation || (this._reportedLocation.x !== location.x)) || (this._reportedLocation.y !== location.y)) || (this._reportedLocation.z !== location.z)) + { + if(!this._reportedLocation) this._reportedLocation = new Vector3d(); + + this._reportedLocation.assign(location); + + this.eventDispatcher.dispatchEvent(new RoomObjectMoveEvent(RoomObjectMoveEvent.POSITION_CHANGED, this.object)); + } + } + } + + if(this.object && this.object.model) this.updateModel(totalTimeRunning, this.object.model); + } + + private updateModel(time: number, model: IRoomObjectModel): void + { + if((this._gestureEndTimestamp > 0) && (time > this._gestureEndTimestamp)) + { + model.setValue(RoomObjectVariable.FIGURE_GESTURE, null); + + this._gestureEndTimestamp = 0; + } + + if(this._talkingEndTimestamp > 0) + { + if(time > this._talkingEndTimestamp) + { + model.setValue(RoomObjectVariable.FIGURE_TALK, 0); + + this._talkingEndTimestamp = 0; + } + } + + if((this._expressionEndTimestamp > 0) && (time > this._expressionEndTimestamp)) + { + model.setValue(RoomObjectVariable.FIGURE_EXPRESSION, 0); + + this._expressionEndTimestamp = 0; + } + } + + public processUpdateMessage(message: RoomObjectUpdateMessage): void + { + if(!message || !this.object) return; + + super.processUpdateMessage(message); + + const model = this.object && this.object.model; + + if(!model) return; + + if(message instanceof ObjectAvatarUpdateMessage) + { + model.setValue(RoomObjectVariable.HEAD_DIRECTION, message.headDirection); + + return; + } + + if(message instanceof ObjectAvatarFigureUpdateMessage) + { + const petFigureData = new PetFigureData(message.figure); + + model.setValue(RoomObjectVariable.FIGURE, message.figure); + model.setValue(RoomObjectVariable.RACE, message.subType); + model.setValue(RoomObjectVariable.PET_PALETTE_INDEX, petFigureData.paletteId); + model.setValue(RoomObjectVariable.PET_COLOR, petFigureData.color); + model.setValue(RoomObjectVariable.PET_TYPE, petFigureData.typeId); + model.setValue(RoomObjectVariable.PET_CUSTOM_LAYER_IDS, petFigureData.customLayerIds); + model.setValue(RoomObjectVariable.PET_CUSTOM_PARTS_IDS, petFigureData.customPartIds); + model.setValue(RoomObjectVariable.PET_CUSTOM_PALETTE_IDS, petFigureData.customPaletteIds); + model.setValue(RoomObjectVariable.PET_IS_RIDING, (message.isRiding ? 1 : 0)); + + return; + } + + if(message instanceof ObjectAvatarPostureUpdateMessage) + { + model.setValue(RoomObjectVariable.FIGURE_POSTURE, message.postureType); + + return; + } + + if(message instanceof ObjectAvatarChatUpdateMessage) + { + model.setValue(RoomObjectVariable.FIGURE_TALK, 1); + + this._talkingEndTimestamp = this.time + (message.numberOfWords * 1000); + + return; + } + + if(message instanceof ObjectAvatarSleepUpdateMessage) + { + model.setValue(RoomObjectVariable.FIGURE_SLEEP, message.isSleeping ? 1 : 0); + + return; + } + + if(message instanceof ObjectAvatarPetGestureUpdateMessage) + { + model.setValue(RoomObjectVariable.FIGURE_GESTURE, message.gesture); + + this._gestureEndTimestamp = this.time + 3000; + + return; + } + + if(message instanceof ObjectAvatarSelectedMessage) + { + this._selected = message.selected; + this._reportedLocation = null; + + return; + } + } + + public mouseEvent(event: RoomSpriteMouseEvent, geometry: IRoomGeometry): void + { + let eventType: string = null; + + switch(event.type) + { + case MouseEventType.MOUSE_CLICK: + eventType = RoomObjectMouseEvent.CLICK; + break; + case MouseEventType.DOUBLE_CLICK: + break; + case MouseEventType.MOUSE_DOWN: { + const petType = this.object.model.getValue(RoomObjectVariable.PET_TYPE); + + if(petType == PetType.MONSTERPLANT) + { + if(this.eventDispatcher) this.eventDispatcher.dispatchEvent(new RoomObjectMouseEvent(RoomObjectMouseEvent.MOUSE_DOWN, this.object, event._Str_3463, event.altKey, event.ctrlKey, event.shiftKey, event.buttonDown)); + } + break; + } + } + + if(eventType && this.eventDispatcher) this.eventDispatcher.dispatchEvent(new RoomObjectMouseEvent(eventType, this.object, event._Str_3463, event.altKey, event.ctrlKey, event.shiftKey, event.buttonDown)); + } +} \ No newline at end of file diff --git a/src/nitro/room/object/logic/room/RoomLogic.ts b/src/nitro/room/object/logic/room/RoomLogic.ts new file mode 100644 index 00000000..762f11db --- /dev/null +++ b/src/nitro/room/object/logic/room/RoomLogic.ts @@ -0,0 +1,459 @@ +import { Point } from 'pixi.js'; +import { RoomObjectEvent } from '../../../../../room/events/RoomObjectEvent'; +import { RoomObjectMouseEvent } from '../../../../../room/events/RoomObjectMouseEvent'; +import { RoomSpriteMouseEvent } from '../../../../../room/events/RoomSpriteMouseEvent'; +import { RoomObjectUpdateMessage } from '../../../../../room/messages/RoomObjectUpdateMessage'; +import { IRoomObjectModel } from '../../../../../room/object/IRoomObjectModel'; +import { RoomObjectLogicBase } from '../../../../../room/object/logic/RoomObjectLogicBase'; +import { ColorConverter } from '../../../../../room/utils/ColorConverter'; +import { IRoomGeometry } from '../../../../../room/utils/IRoomGeometry'; +import { Vector3d } from '../../../../../room/utils/Vector3d'; +import { MouseEventType } from '../../../../ui/MouseEventType'; +import { RoomObjectTileMouseEvent } from '../../../events/RoomObjectTileMouseEvent'; +import { RoomObjectWallMouseEvent } from '../../../events/RoomObjectWallMouseEvent'; +import { ObjectRoomColorUpdateMessage } from '../../../messages/ObjectRoomColorUpdateMessage'; +import { ObjectRoomFloorHoleUpdateMessage } from '../../../messages/ObjectRoomFloorHoleUpdateMessage'; +import { ObjectRoomMapUpdateMessage } from '../../../messages/ObjectRoomMapUpdateMessage'; +import { ObjectRoomMaskUpdateMessage } from '../../../messages/ObjectRoomMaskUpdateMessage'; +import { ObjectRoomPlanePropertyUpdateMessage } from '../../../messages/ObjectRoomPlanePropertyUpdateMessage'; +import { ObjectRoomPlaneVisibilityUpdateMessage } from '../../../messages/ObjectRoomPlaneVisibilityUpdateMessage'; +import { ObjectRoomUpdateMessage } from '../../../messages/ObjectRoomUpdateMessage'; +import { RoomMapData } from '../../RoomMapData'; +import { RoomObjectVariable } from '../../RoomObjectVariable'; +import { RoomPlaneBitmapMaskData } from '../../RoomPlaneBitmapMaskData'; +import { RoomPlaneBitmapMaskParser } from '../../RoomPlaneBitmapMaskParser'; +import { RoomPlaneData } from '../../RoomPlaneData'; +import { RoomPlaneParser } from '../../RoomPlaneParser'; + +export class RoomLogic extends RoomObjectLogicBase +{ + private _planeParser: RoomPlaneParser; + private _planeBitmapMaskParser: RoomPlaneBitmapMaskParser; + private _color: number; + private _Str_3576: number; + private _Str_14932: number; + private _Str_17003: number; + private _Str_11287: number; + private _Str_16460: number; + private _Str_9785: number; + private _Str_17191: number; + private _lastHoleUpdate: number; + private _needsMapUpdate: boolean; + + constructor() + { + super(); + + this._planeParser = new RoomPlaneParser(); + this._planeBitmapMaskParser = new RoomPlaneBitmapMaskParser(); + this._color = 0xFFFFFF; + this._Str_3576 = 0xFF; + this._Str_14932 = 0xFFFFFF; + this._Str_17003 = 0xFF; + this._Str_11287 = 0xFFFFFF; + this._Str_16460 = 0xFF; + this._Str_9785 = 0; + this._Str_17191 = 1500; + this._lastHoleUpdate = 0; + this._needsMapUpdate = false; + } + + public getEventTypes(): string[] + { + const types = [ RoomObjectMouseEvent.MOUSE_MOVE, RoomObjectMouseEvent.CLICK ]; + + return this.mergeTypes(super.getEventTypes(), types); + } + + public dispose(): void + { + super.dispose(); + + if(this._planeParser) + { + this._planeParser.dispose(); + + this._planeParser = null; + } + + if(this._planeBitmapMaskParser) + { + this._planeBitmapMaskParser.dispose(); + + this._planeBitmapMaskParser = null; + } + } + + public initialize(roomMap: RoomMapData): void + { + if(!roomMap || !this.object) return; + + if(!(roomMap instanceof RoomMapData)) return; + + if(!this._planeParser.initializeFromMapData(roomMap)) return; + + this.object.model.setValue(RoomObjectVariable.ROOM_MAP_DATA, roomMap); + this.object.model.setValue(RoomObjectVariable.ROOM_BACKGROUND_COLOR, 0xFFFFFF); + this.object.model.setValue(RoomObjectVariable.ROOM_FLOOR_VISIBILITY, 1); + this.object.model.setValue(RoomObjectVariable.ROOM_WALL_VISIBILITY, 1); + this.object.model.setValue(RoomObjectVariable.ROOM_LANDSCAPE_VISIBILITY, 1); + } + + public update(time: number): void + { + super.update(time); + + this._Str_24703(time); + + if(this._needsMapUpdate) + { + if(this._lastHoleUpdate && (time - this._lastHoleUpdate) < 5) return; + + const model = this.object && this.object.model; + + if(model) + { + const mapData = this._planeParser.getMapData(); + + model.setValue(RoomObjectVariable.ROOM_MAP_DATA, mapData); + model.setValue(RoomObjectVariable.ROOM_FLOOR_HOLE_UPDATE_TIME, time); + + this._planeParser.initializeFromMapData(mapData); + } + + this._lastHoleUpdate = 0; + this._needsMapUpdate = false; + } + + } + + private _Str_24703(k: number): void + { + if(!this.object || !this._Str_9785) return; + + let color = this._color; + let newColor = this._Str_3576; + + if((k - this._Str_9785) >= this._Str_17191) + { + color = this._Str_11287; + newColor = this._Str_16460; + + this._Str_9785 = 0; + } + else + { + let _local_7 = ((this._Str_14932 >> 16) & 0xFF); + let _local_8 = ((this._Str_14932 >> 8) & 0xFF); + let _local_9 = (this._Str_14932 & 0xFF); + + const _local_10 = ((this._Str_11287 >> 16) & 0xFF); + const _local_11 = ((this._Str_11287 >> 8) & 0xFF); + const _local_12 = (this._Str_11287 & 0xFF); + const _local_13 = ((k - this._Str_9785) / this._Str_17191); + + _local_7 = (_local_7 + ((_local_10 - _local_7) * _local_13)); + _local_8 = (_local_8 + ((_local_11 - _local_8) * _local_13)); + _local_9 = (_local_9 + ((_local_12 - _local_9) * _local_13)); + + color = (((_local_7 << 16) + (_local_8 << 8)) + _local_9); + newColor = (this._Str_17003 + ((this._Str_16460 - this._Str_17003) * _local_13)); + + this._color = color; + this._Str_3576 = newColor; + } + + let _local_5 = ColorConverter._Str_22130(color); + + _local_5 = ((_local_5 & 0xFFFF00) + newColor); + color = ColorConverter._Str_13949(_local_5); + + if(this.object.model) this.object.model.setValue(RoomObjectVariable.ROOM_BACKGROUND_COLOR, color); + } + + public processUpdateMessage(message: RoomObjectUpdateMessage): void + { + if(!message || !this.object) return; + + const model = this.object.model; + + if(!model) return; + + if(message instanceof ObjectRoomUpdateMessage) + { + this.onObjectRoomUpdateMessage(message, model); + + return; + } + + if(message instanceof ObjectRoomMaskUpdateMessage) + { + this.onObjectRoomMaskUpdateMessage(message, model); + + return; + } + + if(message instanceof ObjectRoomPlaneVisibilityUpdateMessage) + { + this.onObjectRoomPlaneVisibilityUpdateMessage(message, model); + + return; + } + + if(message instanceof ObjectRoomPlanePropertyUpdateMessage) + { + this.onObjectRoomPlanePropertyUpdateMessage(message, model); + + return; + } + + if(message instanceof ObjectRoomFloorHoleUpdateMessage) + { + this.onObjectRoomFloorHoleUpdateMessage(message, model); + + return; + } + + if(message instanceof ObjectRoomColorUpdateMessage) + { + this.onObjectRoomColorUpdateMessage(message, model); + + return; + } + + if(message instanceof ObjectRoomMapUpdateMessage) + { + this.onObjectRoomMapUpdateMessage(message); + } + } + + private onObjectRoomUpdateMessage(message: ObjectRoomUpdateMessage, model: IRoomObjectModel): void + { + switch(message.type) + { + case ObjectRoomUpdateMessage.ROOM_FLOOR_UPDATE: + model.setValue(RoomObjectVariable.ROOM_FLOOR_TYPE, message.value); + return; + case ObjectRoomUpdateMessage.ROOM_WALL_UPDATE: + model.setValue(RoomObjectVariable.ROOM_WALL_TYPE, message.value); + return; + case ObjectRoomUpdateMessage.ROOM_LANDSCAPE_UPDATE: + model.setValue(RoomObjectVariable.ROOM_LANDSCAPE_TYPE, message.value); + return; + } + } + + private onObjectRoomMaskUpdateMessage(message: ObjectRoomMaskUpdateMessage, _arg_2: IRoomObjectModel): void + { + let maskType: string = null; + let update = false; + + switch(message.type) + { + case ObjectRoomMaskUpdateMessage.ADD_MASK: + maskType = RoomPlaneBitmapMaskData.WINDOW; + + if(message.maskCategory === ObjectRoomMaskUpdateMessage.HOLE) maskType = RoomPlaneBitmapMaskData.HOLE; + + this._planeBitmapMaskParser.addMask(message.maskId, message.maskType, message.maskLocation, maskType); + + update = true; + break; + case ObjectRoomMaskUpdateMessage._Str_10260: + update = this._planeBitmapMaskParser._Str_23574(message.maskId); + break; + + } + + if(update) _arg_2.setValue(RoomObjectVariable.ROOM_PLANE_MASK_XML, this._planeBitmapMaskParser._Str_5598()); + } + + private onObjectRoomPlaneVisibilityUpdateMessage(message: ObjectRoomPlaneVisibilityUpdateMessage, model: IRoomObjectModel): void + { + let visible = 0; + + if(message.visible) visible = 1; + + switch(message.type) + { + case ObjectRoomPlaneVisibilityUpdateMessage.FLOOR_VISIBILITY: + model.setValue(RoomObjectVariable.ROOM_FLOOR_VISIBILITY, visible); + return; + case ObjectRoomPlaneVisibilityUpdateMessage.WALL_VISIBILITY: + model.setValue(RoomObjectVariable.ROOM_WALL_VISIBILITY, visible); + model.setValue(RoomObjectVariable.ROOM_LANDSCAPE_VISIBILITY, visible); + return; + } + } + + private onObjectRoomPlanePropertyUpdateMessage(message: ObjectRoomPlanePropertyUpdateMessage, model: IRoomObjectModel): void + { + switch(message.type) + { + case ObjectRoomPlanePropertyUpdateMessage.FLOOR_THICKNESS: + model.setValue(RoomObjectVariable.ROOM_FLOOR_THICKNESS, message.value); + return; + case ObjectRoomPlanePropertyUpdateMessage.WALL_THICKNESS: + model.setValue(RoomObjectVariable.ROOM_WALL_THICKNESS, message.value); + return; + } + } + + private onObjectRoomFloorHoleUpdateMessage(message: ObjectRoomFloorHoleUpdateMessage, model: IRoomObjectModel): void + { + switch(message.type) + { + case ObjectRoomFloorHoleUpdateMessage.ADD: + this._planeParser.addFloorHole(message.id, message.x, message.y, message.width, message.height); + this._needsMapUpdate = true; + return; + case ObjectRoomFloorHoleUpdateMessage.REMOVE: + this._planeParser.removeFloorHole(message.id); + this._needsMapUpdate = true; + return; + } + + this._lastHoleUpdate = this.time; + } + + private onObjectRoomColorUpdateMessage(message: ObjectRoomColorUpdateMessage, model: IRoomObjectModel): void + { + if(!message || !model) return; + + this._Str_14932 = this._color; + this._Str_17003 = this._Str_3576; + this._Str_11287 = message.color; + this._Str_16460 = message.light; + this._Str_9785 = this.time; + this._Str_17191 = 1500; + + model.setValue(RoomObjectVariable.ROOM_COLORIZE_BG_ONLY, message.backgroundOnly); + } + + private onObjectRoomMapUpdateMessage(message: ObjectRoomMapUpdateMessage): void + { + if(!message || !message.mapData) return; + + this.object.model.setValue(RoomObjectVariable.ROOM_MAP_DATA, message.mapData); + this.object.model.setValue(RoomObjectVariable.ROOM_FLOOR_HOLE_UPDATE_TIME, this.time); + + this._planeParser.initializeFromMapData(message.mapData); + } + + public mouseEvent(event: RoomSpriteMouseEvent, geometry: IRoomGeometry): void + { + if(!event || !geometry || !this.object || !this.object.model) return; + + const tag = event.spriteTag; + + let planeId = 0; + + if(tag && (tag.indexOf('@') >= 0)) + { + planeId = parseInt(tag.substr(tag.indexOf('@') + 1)); + } + + if((planeId < 1) || (planeId > this._planeParser.planeCount)) + { + if(event.type === MouseEventType.ROLL_OUT) + { + this.object.model.setValue(RoomObjectVariable.ROOM_SELECTED_PLANE, 0); + } + + return; + } + + planeId--; + + let _local_7: Point = null; + + const _local_8 = this._planeParser.getPlaneLocation(planeId); + const _local_9 = this._planeParser.getPlaneLeftSide(planeId); + const _local_10 = this._planeParser.getPlaneRightSide(planeId); + const _local_11 = this._planeParser.getPlaneNormalDirection(planeId); + const _local_12 = this._planeParser.getPlaneType(planeId); + + if(((((_local_8 == null) || (_local_9 == null)) || (_local_10 == null)) || (_local_11 == null))) return; + + const _local_13 = _local_9.length; + const _local_14 = _local_10.length; + + if(((_local_13 == 0) || (_local_14 == 0))) return; + + const _local_15 = event.screenX; + const _local_16 = event.screenY; + const _local_17 = new Point(_local_15, _local_16); + + _local_7 = geometry.getPlanePosition(_local_17, _local_8, _local_9, _local_10); + + if(!_local_7) + { + this.object.model.setValue(RoomObjectVariable.ROOM_SELECTED_PLANE, 0); + + return; + } + + const _local_18 = Vector3d.product(_local_9, (_local_7.x / _local_13)); + + _local_18.add(Vector3d.product(_local_10, (_local_7.y / _local_14))); + _local_18.add(_local_8); + + const _local_19 = _local_18.x; + const _local_20 = _local_18.y; + const _local_21 = _local_18.z; + + if(((((_local_7.x >= 0) && (_local_7.x < _local_13)) && (_local_7.y >= 0)) && (_local_7.y < _local_14))) + { + this.object.model.setValue(RoomObjectVariable.ROOM_SELECTED_X, _local_19); + this.object.model.setValue(RoomObjectVariable.ROOM_SELECTED_Y, _local_20); + this.object.model.setValue(RoomObjectVariable.ROOM_SELECTED_Z, _local_21); + this.object.model.setValue(RoomObjectVariable.ROOM_SELECTED_PLANE, (planeId + 1)); + } + else + { + this.object.model.setValue(RoomObjectVariable.ROOM_SELECTED_PLANE, 0); + + return; + } + + let eventType: string = null; + + if((event.type === MouseEventType.MOUSE_MOVE) || (event.type === MouseEventType.ROLL_OVER)) eventType = RoomObjectMouseEvent.MOUSE_MOVE; + else if((event.type === MouseEventType.MOUSE_CLICK)) eventType = RoomObjectMouseEvent.CLICK; + + switch(event.type) + { + case MouseEventType.MOUSE_MOVE: + case MouseEventType.ROLL_OVER: + case MouseEventType.MOUSE_CLICK: { + let newEvent: RoomObjectEvent = null; + + if(_local_12 === RoomPlaneData.PLANE_FLOOR) + { + newEvent = new RoomObjectTileMouseEvent(eventType, this.object, event._Str_3463, _local_19, _local_20, _local_21, event.altKey, event.ctrlKey, event.shiftKey, event.buttonDown); + } + + else if((_local_12 === RoomPlaneData.PLANE_WALL) || (_local_12 === RoomPlaneData.PLANE_LANDSCAPE)) + { + let direction = 90; + + if(_local_11) + { + direction = (_local_11.x + 90); + + if(direction > 360) direction -= 360; + } + + const _local_27 = ((_local_9.length * _local_7.x) / _local_13); + const _local_28 = ((_local_10.length * _local_7.y) / _local_14); + + newEvent = new RoomObjectWallMouseEvent(eventType, this.object, event._Str_3463, _local_8, _local_9, _local_10, _local_27, _local_28, direction, event.altKey, event.ctrlKey, event.shiftKey, event.buttonDown); + } + + if(this.eventDispatcher) this.eventDispatcher.dispatchEvent(newEvent); + + return; + } + } + } +} diff --git a/src/nitro/room/object/logic/room/SelectionArrowLogic.ts b/src/nitro/room/object/logic/room/SelectionArrowLogic.ts new file mode 100644 index 00000000..056a4936 --- /dev/null +++ b/src/nitro/room/object/logic/room/SelectionArrowLogic.ts @@ -0,0 +1,37 @@ +import { IAssetData } from '../../../../../core/asset/interfaces'; +import { RoomObjectUpdateMessage } from '../../../../../room/messages/RoomObjectUpdateMessage'; +import { RoomObjectLogicBase } from '../../../../../room/object/logic/RoomObjectLogicBase'; +import { ObjectVisibilityUpdateMessage } from '../../../messages/ObjectVisibilityUpdateMessage'; +import { RoomObjectVariable } from '../../RoomObjectVariable'; + +export class SelectionArrowLogic extends RoomObjectLogicBase +{ + public initialize(data: IAssetData): void + { + if(!this.object) return; + + this.object.model.setValue(RoomObjectVariable.FURNITURE_ALPHA_MULTIPLIER, 1); + + this.object.setState(1, 0); + } + + public processUpdateMessage(message: RoomObjectUpdateMessage): void + { + super.processUpdateMessage(message); + + if(!(message instanceof ObjectVisibilityUpdateMessage)) return; + + if(this.object) + { + switch(message.type) + { + case ObjectVisibilityUpdateMessage.ENABLED: + this.object.setState(0, 0); + return; + case ObjectVisibilityUpdateMessage.DISABLED: + this.object.setState(1, 0); + return; + } + } + } +} \ No newline at end of file diff --git a/src/nitro/room/object/logic/room/TileCursorLogic.ts b/src/nitro/room/object/logic/room/TileCursorLogic.ts new file mode 100644 index 00000000..2827265e --- /dev/null +++ b/src/nitro/room/object/logic/room/TileCursorLogic.ts @@ -0,0 +1,66 @@ +import { IAssetData } from '../../../../../core/asset/interfaces'; +import { RoomObjectUpdateMessage } from '../../../../../room/messages/RoomObjectUpdateMessage'; +import { RoomObjectLogicBase } from '../../../../../room/object/logic/RoomObjectLogicBase'; +import { ObjectTileCursorUpdateMessage } from '../../../messages/ObjectTileCursorUpdateMessage'; +import { RoomObjectVariable } from '../../RoomObjectVariable'; + +export class TileCursorLogic extends RoomObjectLogicBase +{ + private static CURSOR_VISIBLE_STATE: number = 0; + private static CURSOR_HIDDEN_STATE: number = 1; + private static CURSOR_HEIGHT_STATE: number = 6; + + private _lastEventId: string; + private _isHidden: boolean; + + constructor() + { + super(); + + this._lastEventId = null; + this._isHidden = false; + } + + public initialize(data: IAssetData): void + { + if(!this.object) return; + + this.object.model.setValue(RoomObjectVariable.FURNITURE_ALPHA_MULTIPLIER, 1); + + this.object.setState(TileCursorLogic.CURSOR_HIDDEN_STATE, 0); + } + + public processUpdateMessage(message: RoomObjectUpdateMessage): void + { + if(!(message instanceof ObjectTileCursorUpdateMessage)) return; + + if(this._lastEventId && (this._lastEventId === message._Str_20637)) return; + + if(message.toggleVisibility) this._isHidden = !this._isHidden; + + super.processUpdateMessage(message); + + if(this.object) + { + if(this._isHidden) + { + this.object.setState(TileCursorLogic.CURSOR_HIDDEN_STATE, 0); + } + else + { + if(!message.visible) + { + this.object.setState(TileCursorLogic.CURSOR_HIDDEN_STATE, 0); + } + else + { + this.object.model.setValue(RoomObjectVariable.TILE_CURSOR_HEIGHT, message.height); + + this.object.setState((message.height > 0.8) ? TileCursorLogic.CURSOR_HEIGHT_STATE : TileCursorLogic.CURSOR_VISIBLE_STATE); + } + } + } + + this._lastEventId = message._Str_20637; + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/avatar/AvatarVisualization.ts b/src/nitro/room/object/visualization/avatar/AvatarVisualization.ts new file mode 100644 index 00000000..98e7a196 --- /dev/null +++ b/src/nitro/room/object/visualization/avatar/AvatarVisualization.ts @@ -0,0 +1,1115 @@ +import { BLEND_MODES, Texture } from 'pixi.js'; +import { AdvancedMap } from '../../../../../core/utils/AdvancedMap'; +import { AlphaTolerance } from '../../../../../room/object/enum/AlphaTolerance'; +import { RoomObjectSpriteType } from '../../../../../room/object/enum/RoomObjectSpriteType'; +import { IRoomObject } from '../../../../../room/object/IRoomObject'; +import { IRoomObjectModel } from '../../../../../room/object/IRoomObjectModel'; +import { IObjectVisualizationData } from '../../../../../room/object/visualization/IRoomObjectVisualizationData'; +import { RoomObjectSpriteVisualization } from '../../../../../room/object/visualization/RoomObjectSpriteVisualization'; +import { IGraphicAsset } from '../../../../../room/object/visualization/utils/IGraphicAsset'; +import { IRoomGeometry } from '../../../../../room/utils/IRoomGeometry'; +import { AvatarAction } from '../../../../avatar/enum/AvatarAction'; +import { AvatarSetType } from '../../../../avatar/enum/AvatarSetType'; +import { IAvatarEffectListener } from '../../../../avatar/IAvatarEffectListener'; +import { IAvatarImage } from '../../../../avatar/IAvatarImage'; +import { IAvatarImageListener } from '../../../../avatar/IAvatarImageListener'; +import { Nitro } from '../../../../Nitro'; +import { RoomObjectVariable } from '../../RoomObjectVariable'; +import { ExpressionAdditionFactory } from './additions/ExpressionAdditionFactory'; +import { FloatingIdleZAddition } from './additions/FloatingIdleZAddition'; +import { IAvatarAddition } from './additions/IAvatarAddition'; +import { MutedBubbleAddition } from './additions/MutedBubbleAddition'; +import { NumberBubbleAddition } from './additions/NumberBubbleAddition'; +import { TypingBubbleAddition } from './additions/TypingBubbleAddition'; +import { AvatarVisualizationData } from './AvatarVisualizationData'; + +export class AvatarVisualization extends RoomObjectSpriteVisualization implements IAvatarImageListener, IAvatarEffectListener +{ + private static AVATAR: string = 'avatar'; + private static FLOATING_IDLE_Z_ID: number = 1; + private static TYPING_BUBBLE_ID: number = 2; + private static EXPRESSION_ID: number = 3; + private static NUMBER_BUBBLE_ID: number = 4; + private static MUTED_BUBBLE_ID: number = 6; + private static OWN_USER_ID: number = 4; + private static UPDATE_TIME_INCREASER: number = 41; + private static OFFSET_MULTIPLIER: number = 1000; + private static AVATAR_LAYER_ID: number = 0; + private static SHADOW_LAYER_ID: number = 1; + private static _Str_17502: number = 97; + private static _Str_11587: number = 2; + private static _Str_14491: number = 2; + private static _Str_18338: number[] = [0, 0, 0]; + private static MAX_EFFECT_CACHE: number = 2; + private static _Str_9540: number = 0; + private static _Str_12370: number = 1000; + private static _Str_11358: number = -0.01; + private static _Str_17708: number = 0.001; + private static _Str_9235: number = -0.409; + + protected _data: AvatarVisualizationData; + + private _avatarImage: IAvatarImage; + private _cachedAvatars: AdvancedMap; + private _cachedAvatarEffects: AdvancedMap; + private _shadow: IGraphicAsset; + private _lastUpdate: number; + private _disposed: boolean; + + private _figure: string; + private _gender: string; + private _direction: number; + private _headDirection: number; + private _posture: string; + private _postureParameter: string; + private _canStandUp: boolean; + private _postureOffset: number; + private _verticalOffset: number; + private _angle: number; + private _headAngle: number; + private _talk: boolean; + private _expression: number; + private _sleep: boolean; + private _blink: boolean; + private _gesture: number; + private _sign: number; + private _highlightEnabled: boolean; + private _highlight: boolean; + private _dance: number; + private _effect: number; + private _carryObject: number; + private _useObject: number; + private _ownUser: boolean; + + private _Str_8935: boolean; + private _Str_17860: boolean; + private _Str_1222: boolean; + private _Str_16697: number; + private _Str_12697: number; + private _Str_14276: number; + + private _isAvatarReady: boolean; + private _needsUpdate: boolean; + private _geometryUpdateCounter: number; + + private _additions: Map; + + constructor() + { + super(); + + this._data = null; + + this._avatarImage = null; + this._cachedAvatars = new AdvancedMap(); + this._cachedAvatarEffects = new AdvancedMap(); + this._shadow = null; + this._lastUpdate = -1000; + this._disposed = false; + + this._figure = null; + this._gender = null; + this._direction = -1; + this._headDirection = -1; + this._posture = ''; + this._postureParameter = ''; + this._canStandUp = false; + this._postureOffset = 0; + this._verticalOffset = 0; + this._angle = -1; + this._headAngle = -1; + this._talk = false; + this._expression = 0; + this._sleep = false; + this._blink = false; + this._gesture = 0; + this._sign = -1; + this._highlightEnabled = false; + this._highlight = false; + this._dance = 0; + this._effect = 0; + this._carryObject = 0; + this._useObject = 0; + this._ownUser = false; + + this._Str_8935 = false; + this._Str_17860 = false; + this._Str_1222 = false; + this._Str_16697 = 2; + this._Str_12697 = 0; + this._Str_14276 = 0; + + this._isAvatarReady = false; + this._needsUpdate = false; + this._geometryUpdateCounter = -1; + + this._additions = new Map(); + } + + public initialize(data: IObjectVisualizationData): boolean + { + if(!(data instanceof AvatarVisualizationData)) return false; + + this._data = data; + + this.setSpriteCount(AvatarVisualization._Str_11587); + + super.initialize(data); + + return true; + } + + public dispose(): void + { + if(this._disposed) return; + + super.dispose(); + + if(this._avatarImage) this._avatarImage.dispose(); + + this._shadow = null; + this._disposed = true; + } + + public update(geometry: IRoomGeometry, time: number, update: boolean, skipUpdate: boolean): void + { + if(!this.object || !geometry || !this._data) return; + + if(time < (this._lastUpdate + AvatarVisualization.UPDATE_TIME_INCREASER)) return; + + this._lastUpdate += AvatarVisualization.UPDATE_TIME_INCREASER; + + if((this._lastUpdate + AvatarVisualization.UPDATE_TIME_INCREASER) < time) this._lastUpdate = (time - AvatarVisualization.UPDATE_TIME_INCREASER); + + const model = this.object.model; + const scale = geometry.scale; + const effect = this._effect; + + let didScaleUpdate = false; + let didEffectUpdate = false; + let otherUpdate = false; + let objectUpdate = false; + + const updateModel = this.updateModel(model, scale); + + if((updateModel || (scale !== this._scale)) || !this._avatarImage) + { + if(scale !== this._scale) + { + didScaleUpdate = true; + + this.updateScale(scale); + } + + if(effect !== this._effect) didEffectUpdate = true; + + if(didScaleUpdate || !this._avatarImage || didEffectUpdate) + { + this._avatarImage = this.createAvatarImage(scale, this._effect); + + if(!this._avatarImage) return; + + otherUpdate = true; + + const sprite = this.getSprite(AvatarVisualization.AVATAR_LAYER_ID); + + if((sprite && this._avatarImage) && this._avatarImage.isPlaceholder()) + { + sprite.alpha = 150; + } + + else if(sprite) + { + sprite.alpha = 255; + } + } + + if(!this._avatarImage) return; + + if(didEffectUpdate && this._avatarImage.animationHasResetOnToggle) this._avatarImage.resetAnimationFrameCounter(); + + this.updateShadow(scale); + + objectUpdate = this.updateObject(this.object, geometry, update, true); + + this.processActionsForAvatar(this._avatarImage); + + if(this._additions) + { + let index = this._Str_16697; + + for(const addition of this._additions.values()) + { + addition.update(this.getSprite(index++), scale); + } + } + + this._scale = scale; + } + else + { + objectUpdate = this.updateObject(this.object, geometry, update); + } + + if(this._additions) + { + let index = this._Str_16697; + + for(const addition of this._additions.values()) + { + if(addition.animate(this.getSprite(index++))) this.updateSpriteCounter++; + } + } + + const update1 = (objectUpdate || updateModel || didScaleUpdate); + const update2 = ((this._Str_1222 || (this._Str_12697 > 0)) && update); + + if(update1) this._Str_12697 = AvatarVisualization._Str_14491; + + if(update1 || update2) + { + this.updateSpriteCounter++; + + this._Str_12697--; + this._Str_14276--; + + if((((this._Str_14276 <= 0) || didScaleUpdate) || updateModel) || otherUpdate) + { + this._avatarImage.updateAnimationByFrames(1); + + this._Str_14276 = AvatarVisualization._Str_14491; + } + else + { + return; + } + + let _local_20 = this._avatarImage.getCanvasOffsets(); + + if(!_local_20 || (_local_20.length < 3)) _local_20 = AvatarVisualization._Str_18338; + + const sprite = this.getSprite(AvatarVisualization._Str_9540); + + if(sprite) + { + const highlightEnabled = ((this.object.model.getValue(RoomObjectVariable.FIGURE_HIGHLIGHT_ENABLE) === 1) && (this.object.model.getValue(RoomObjectVariable.FIGURE_HIGHLIGHT) === 1)); + + const avatarImage = this._avatarImage.getImage(AvatarSetType.FULL, highlightEnabled); + + if(avatarImage) + { + sprite.texture = avatarImage; + + if(highlightEnabled) + { + // sprite.filters = [ + // new GlowFilter({ + // color: 0xFFFFFF, + // distance: 6 + // }) + // ]; + } + else + { + sprite.filters = []; + } + } + + if(sprite.texture) + { + sprite.offsetX = ((((-1 * scale) / 2) + _local_20[0]) - ((sprite.texture.width - scale) / 2)); + sprite.offsetY = (((-(sprite.texture.height) + (scale / 4)) + _local_20[1]) + this._postureOffset); + } + + if(this._Str_8935) + { + if(this._Str_17860) sprite.relativeDepth = -0.5; + else sprite.relativeDepth = (AvatarVisualization._Str_9235 + _local_20[2]); + } + else + { + sprite.relativeDepth = (AvatarVisualization._Str_11358 + _local_20[2]); + } + + if(this._ownUser) + { + sprite.relativeDepth -= AvatarVisualization._Str_17708; + sprite.spriteType = RoomObjectSpriteType._Str_10494; + } + else + { + sprite.spriteType = RoomObjectSpriteType._Str_11629; + } + } + + const typingBubble = this.getAddition(AvatarVisualization.TYPING_BUBBLE_ID) as TypingBubbleAddition; + + if(typingBubble) + { + if(!this._Str_8935) typingBubble.relativeDepth = ((AvatarVisualization._Str_11358 - 0.01) + _local_20[2]); + else typingBubble.relativeDepth = ((AvatarVisualization._Str_9235 - 0.01) + _local_20[2]); + } + + this._Str_1222 = this._avatarImage.isAnimating(); + + let _local_21 = AvatarVisualization._Str_11587; + const direction = this._avatarImage.getDirection(); + + for(const spriteData of this._avatarImage.getSprites()) + { + if(spriteData.id === AvatarVisualization.AVATAR) + { + const sprite = this.getSprite(AvatarVisualization._Str_9540); + + if(sprite) + { + const layerData = this._avatarImage.getLayerData(spriteData); + + let offsetX = spriteData._Str_809(direction); + let offsetY = spriteData._Str_739(direction); + + if(layerData) + { + offsetX += layerData.dx; + offsetY += layerData.dy; + } + + if(scale < 48) + { + offsetX /= 2; + offsetY /= 2; + } + + if(!this._canStandUp) + { + sprite.offsetX += offsetX; + sprite.offsetY += offsetY; + } + } + } + else + { + const sprite = this.getSprite(_local_21); + + if(sprite) + { + sprite.alphaTolerance = AlphaTolerance._Str_9268; + sprite.visible = true; + + const layerData = this._avatarImage.getLayerData(spriteData); + + let frameNumber = 0; + let offsetX = spriteData._Str_809(direction); + let offsetY = spriteData._Str_739(direction); + const offsetZ = spriteData._Str_839(direction); + let dd = 0; + + if(spriteData._Str_949) dd = direction; + + if(layerData) + { + frameNumber = layerData._Str_891; + offsetX += layerData.dx; + offsetY += layerData.dy; + dd += layerData.dd; + } + + if(scale < 48) + { + offsetX /= 2; + offsetY /= 2; + } + + if(dd < 0) dd += 8; + else + { + if(dd > 7) dd -= 8; + } + + const assetName = ((((((this._avatarImage.getScale() + '_') + spriteData.member) + '_') + dd) + '_') + frameNumber); + + const asset = this._avatarImage.getAsset(assetName); + + if(!asset) continue; + + sprite.texture = asset.texture; + sprite.offsetX = ((asset.offsetX - (scale / 2)) + offsetX); + sprite.offsetY = (asset.offsetY + offsetY); + sprite.flipH = asset.flipH; + + if(spriteData._Str_767) + { + sprite.offsetY += ((this._verticalOffset * scale) / (2 * AvatarVisualization._Str_12370)); + } + else + { + sprite.offsetY += this._postureOffset; + } + + if(this._Str_8935) + { + sprite.relativeDepth = (AvatarVisualization._Str_9235 - ((0.001 * this.totalSprites) * offsetZ)); + } + else + { + sprite.relativeDepth = (AvatarVisualization._Str_11358 - ((0.001 * this.totalSprites) * offsetZ)); + } + + if(spriteData.ink === 33) sprite.blendMode = BLEND_MODES.ADD; + else sprite.blendMode = BLEND_MODES.NORMAL; + } + + _local_21++; + } + } + } + } + + private createAvatarImage(scale: number, effectId: number): IAvatarImage + { + let cachedImage: IAvatarImage = null; + let imageName = 'avatarImage' + scale.toString(); + + if(!effectId) + { + cachedImage = this._cachedAvatars.getValue(imageName); + } + else + { + imageName += '-' + effectId; + + cachedImage = this._cachedAvatarEffects.getValue(imageName); + } + + if(!cachedImage) + { + cachedImage = this._data.createAvatarImage(this._figure, scale, this._gender, this, this); + + if(cachedImage) + { + if(!effectId) + { + this._cachedAvatars.add(imageName, cachedImage); + } + + else + { + if(this._cachedAvatarEffects.length >= AvatarVisualization.MAX_EFFECT_CACHE) + { + const cached = this._cachedAvatarEffects.remove(this._cachedAvatarEffects.getKey(0)); + + if(cached) cached.dispose(); + } + + this._cachedAvatarEffects.add(imageName, cachedImage); + } + } + } + + return cachedImage; + } + + protected updateObject(object: IRoomObject, geometry: IRoomGeometry, update: boolean, _arg_4: boolean = false): boolean + { + if((!_arg_4 && (this.updateObjectCounter === object.updateCounter)) && (this._geometryUpdateCounter === geometry.updateId)) return false; + + let direction = (object.getDirection().x - geometry.direction.x); + let headDirection = (this._headDirection - geometry.direction.x); + + if(this._posture === 'float') headDirection = direction; + + direction = (((direction % 360) + 360) % 360); + headDirection = (((headDirection % 360) + 360) % 360); + + if((this._posture === 'sit') && this._canStandUp) + { + direction -= ((direction % 90) - 45); + headDirection -= ((headDirection % 90) - 45); + } + + if((direction !== this._angle) || _arg_4) + { + update = true; + + this._angle = direction; + + direction = (direction - (135 - 22.5)); + direction = ((direction + 360) % 360); + + this._avatarImage.setDirectionAngle(AvatarSetType.FULL, direction); + } + + if((headDirection !== this._headAngle) || _arg_4) + { + update = true; + + this._headAngle = headDirection; + + if(this._headAngle !== this._angle) + { + headDirection = (headDirection - (135 - 22.5)); + headDirection = ((headDirection + 360) % 360); + + this._avatarImage.setDirectionAngle(AvatarSetType.HEAD, headDirection); + } + } + + this._geometryUpdateCounter = geometry.updateId; + + this.updateObjectCounter = this.object.updateCounter; + + return update; + } + + protected updateModel(model: IRoomObjectModel, scale: number): boolean + { + if(!model) return false; + + if(this.updateModelCounter === model.updateCounter) return false; + + let needsUpdate = false; + + const talk = (model.getValue(RoomObjectVariable.FIGURE_TALK) > 0); + + if(talk !== this._talk) + { + this._talk = talk; + + needsUpdate = true; + } + + const expression = model.getValue(RoomObjectVariable.FIGURE_EXPRESSION); + + if(expression !== this._expression) + { + this._expression = expression; + + needsUpdate = true; + } + + const sleep = (model.getValue(RoomObjectVariable.FIGURE_SLEEP) > 0); + + if(sleep !== this._sleep) + { + this._sleep = sleep; + + needsUpdate = true; + } + + const blink = (model.getValue(RoomObjectVariable.FIGURE_BLINK) > 0); + + if(blink !== this._blink) + { + this._blink = blink; + + needsUpdate = true; + } + + const gesture = (model.getValue(RoomObjectVariable.FIGURE_GESTURE) || 0); + + if(gesture !== this._gesture) + { + this._gesture = gesture; + + needsUpdate = true; + } + + const posture = model.getValue(RoomObjectVariable.FIGURE_POSTURE); + + if(posture !== this._posture) + { + this._posture = posture; + + needsUpdate = true; + } + + const postureParameter = model.getValue(RoomObjectVariable.FIGURE_POSTURE_PARAMETER); + + if(postureParameter !== this._postureParameter) + { + this._postureParameter = postureParameter; + + needsUpdate = true; + } + + const canStandUp = model.getValue(RoomObjectVariable.FIGURE_CAN_STAND_UP); + + if(canStandUp !== this._canStandUp) + { + this._canStandUp = canStandUp; + + needsUpdate = true; + } + + const verticalOffset = (model.getValue(RoomObjectVariable.FIGURE_VERTICAL_OFFSET) * AvatarVisualization.OFFSET_MULTIPLIER); + + if(verticalOffset !== this._verticalOffset) + { + this._verticalOffset = verticalOffset; + + needsUpdate = true; + } + + const dance = (model.getValue(RoomObjectVariable.FIGURE_DANCE) || 0); + + if(dance !== this._dance) + { + this._dance = dance; + + needsUpdate = true; + } + + const effect = (model.getValue(RoomObjectVariable.FIGURE_EFFECT) || 0); + + if(effect !== this._effect) + { + this._effect = effect; + + needsUpdate = true; + } + + const carryObject = (model.getValue(RoomObjectVariable.FIGURE_CARRY_OBJECT) || 0); + + if(carryObject !== this._carryObject) + { + this._carryObject = carryObject; + + needsUpdate = true; + } + + const useObject = (model.getValue(RoomObjectVariable.FIGURE_USE_OBJECT) || 0); + + if(useObject !== this._useObject) + { + this._useObject = useObject; + + needsUpdate = true; + } + + const headDirection = model.getValue(RoomObjectVariable.HEAD_DIRECTION); + + if(headDirection !== this._headDirection) + { + this._headDirection = headDirection; + + needsUpdate = true; + } + + if((this._carryObject > 0) && (useObject > 0)) + { + if(this._useObject !== this._carryObject) + { + this._useObject = this._carryObject; + + needsUpdate = true; + } + } + else + { + if(this._useObject !== 0) + { + this._useObject = 0; + + needsUpdate = true; + } + } + + let idleAddition = this.getAddition(AvatarVisualization.FLOATING_IDLE_Z_ID); + + if(this._sleep) + { + if(!idleAddition) idleAddition = this.addAddition(new FloatingIdleZAddition(AvatarVisualization.FLOATING_IDLE_Z_ID, this)); + + needsUpdate = true; + } + else + { + if(idleAddition) this.removeAddition(AvatarVisualization.FLOATING_IDLE_Z_ID); + } + + const isMuted = (model.getValue(RoomObjectVariable.FIGURE_IS_MUTED) > 0); + + let mutedAddition = this.getAddition(AvatarVisualization.MUTED_BUBBLE_ID); + + if(isMuted) + { + if(!mutedAddition) mutedAddition = this.addAddition(new MutedBubbleAddition(AvatarVisualization.MUTED_BUBBLE_ID, this)); + + needsUpdate = true; + } + else + { + if(mutedAddition) + { + this.removeAddition(AvatarVisualization.MUTED_BUBBLE_ID); + + needsUpdate = true; + } + + const isTyping = (model.getValue(RoomObjectVariable.FIGURE_IS_TYPING) > 0); + + let typingAddition = this.getAddition(AvatarVisualization.TYPING_BUBBLE_ID); + + if(isTyping) + { + if(!typingAddition) typingAddition = this.addAddition(new TypingBubbleAddition(AvatarVisualization.TYPING_BUBBLE_ID, this)); + + needsUpdate = true; + } + else + { + if(typingAddition) this.removeAddition(AvatarVisualization.TYPING_BUBBLE_ID); + } + } + + const numberValue = model.getValue(RoomObjectVariable.FIGURE_NUMBER_VALUE); + + let numberAddition = this.getAddition(AvatarVisualization.NUMBER_BUBBLE_ID); + + if(numberValue > 0) + { + if(!numberAddition) numberAddition = this.addAddition(new NumberBubbleAddition(AvatarVisualization.NUMBER_BUBBLE_ID, numberValue, this)); + + needsUpdate = true; + } + else + { + if(numberAddition) this.removeAddition(AvatarVisualization.NUMBER_BUBBLE_ID); + } + + let expressionAddition = this.getAddition(AvatarVisualization.EXPRESSION_ID); + + if(this._expression > 0) + { + if(!expressionAddition) + { + expressionAddition = ExpressionAdditionFactory.getExpressionAddition(AvatarVisualization.EXPRESSION_ID, this._expression, this); + + if(expressionAddition) this.addAddition(expressionAddition); + } + } + else + { + if(expressionAddition) this.removeAddition(AvatarVisualization.EXPRESSION_ID); + } + + this.updateScale(scale); + + const gender = model.getValue(RoomObjectVariable.GENDER); + + if(gender !== this._gender) + { + this._gender = gender; + + needsUpdate = true; + } + + if(this.updateFigure(model.getValue(RoomObjectVariable.FIGURE))) needsUpdate = true; + + let sign = model.getValue(RoomObjectVariable.FIGURE_SIGN); + + if(sign === null) sign = -1; + + if(this._sign !== sign) + { + this._sign = sign; + + needsUpdate = true; + } + + const highlightEnabled = (model.getValue(RoomObjectVariable.FIGURE_HIGHLIGHT_ENABLE) > 0); + + if(highlightEnabled !== this._highlightEnabled) + { + this._highlightEnabled = highlightEnabled; + + needsUpdate = true; + } + + if(this._highlightEnabled) + { + const highlight = (model.getValue(RoomObjectVariable.FIGURE_HIGHLIGHT) > 0); + + if(highlight !== this._highlight) + { + this._highlight = highlight; + + needsUpdate = true; + } + } + + const ownUser = (model.getValue(RoomObjectVariable.OWN_USER) > 0); + + if(ownUser !== this._ownUser) + { + this._ownUser = ownUser; + + needsUpdate = true; + } + + this.updateModelCounter = model.updateCounter; + + return needsUpdate; + } + + protected setDirection(direction: number): void + { + if(this._direction === direction) return; + + this._direction = direction; + + this._needsUpdate = true; + } + + private updateScale(scale: number): void + { + if(scale < 48) this._blink = false; + + if((this._posture === 'sit') || (this._posture === 'lay')) + { + this._postureOffset = (scale / 2); + } + else + { + this._postureOffset = 0; + } + + this._Str_17860 = false; + this._Str_8935 = false; + + if(this._posture === 'lay') + { + this._Str_8935 = true; + + const _local_2 = parseInt(this._postureParameter); + + if(_local_2 < 0) this._Str_17860 = true; + } + } + + private processActionsForAvatar(avatar: IAvatarImage): void + { + if(!avatar) return; + + avatar.initActionAppends(); + + avatar.appendAction(AvatarAction.POSTURE, this._posture, this._postureParameter); + + if(this._gesture > 0) this._avatarImage.appendAction(AvatarAction.GESTURE, AvatarAction.getGesture(this._gesture)); + + if(this._dance > 0) this._avatarImage.appendAction(AvatarAction.DANCE, this._dance); + + if(this._sign > -1) this._avatarImage.appendAction(AvatarAction.SIGN, this._sign); + + if(this._carryObject > 0) this._avatarImage.appendAction(AvatarAction.CARRY_OBJECT, this._carryObject); + + if(this._useObject > 0) this._avatarImage.appendAction(AvatarAction.USE_OBJECT, this._useObject); + + if(this._talk) this._avatarImage.appendAction(AvatarAction.TALK); + + if(this._sleep || this._blink) this._avatarImage.appendAction(AvatarAction.SLEEP); + + if(this._expression > 0) + { + const expression = AvatarAction.getExpression(this._expression); + + if(expression !== '') + { + switch(expression) + { + case AvatarAction.DANCE: + this._avatarImage.appendAction(AvatarAction.DANCE, 2); + break; + default: + this._avatarImage.appendAction(expression); + break; + } + } + } + + if(this._effect > 0) this._avatarImage.appendAction(AvatarAction.EFFECT, this._effect); + + avatar.endActionAppends(); + + this._Str_1222 = avatar.isAnimating(); + + let spriteCount = AvatarVisualization._Str_11587; + + for(const sprite of this._avatarImage.getSprites()) + { + if(sprite.id !== AvatarVisualization.AVATAR) spriteCount++; + } + + if(spriteCount !== this.totalSprites) this.setSpriteCount(spriteCount); + + this._Str_16697 = spriteCount; + + if(this._additions) + { + for(const addition of this._additions.values()) this.createSprite(); + } + } + + private updateFigure(figure: string): boolean + { + if(this._figure === figure) return false; + + this._figure = figure; + + this.clearAvatar(); + + return true; + } + + public resetFigure(figure: string): void + { + this.clearAvatar(); + } + + public resetEffect(effect: number): void + { + this.clearAvatar(); + } + + private clearAvatar(): void + { + for(const avatar of this._cachedAvatars.getValues()) avatar && avatar.dispose(); + + for(const avatar of this._cachedAvatarEffects.getValues()) avatar && avatar.dispose(); + + this._cachedAvatars.reset(); + this._cachedAvatarEffects.reset(); + + this._avatarImage = null; + + const sprite = this.getSprite(AvatarVisualization.AVATAR_LAYER_ID); + + if(sprite) + { + sprite.texture = Texture.EMPTY; + sprite.alpha = 255; + } + } + + private getAddition(id: number): IAvatarAddition + { + if(!this._additions) return null; + + const existing = this._additions.get(id); + + if(!existing) return null; + + return existing; + } + + private addAddition(addition: IAvatarAddition): IAvatarAddition + { + const existing = this.getAddition(addition.id); + + if(existing) return; + + this._additions.set(addition.id, addition); + + return addition; + } + + private removeAddition(id: number): void + { + const addition = this.getAddition(id); + + if(!addition) return; + + this._additions.delete(addition.id); + + addition.dispose(); + } + + private updateShadow(scale: number): void + { + this._shadow = null; + + const sprite = this.getSprite(AvatarVisualization.SHADOW_LAYER_ID); + + if(!sprite) return; + + let hasShadow = (((this._posture === 'mv') || (this._posture === 'std')) || ((this._posture === 'sit') && this._canStandUp)); + + if(this._effect === AvatarVisualization._Str_17502) hasShadow = false; + + if(hasShadow) + { + sprite.visible = true; + + if(!this._shadow || (scale !== this._scale)) + { + let offsetX = 0; + let offsetY = 0; + + if(scale < 48) + { + sprite._Str_3582 = 'sh_std_sd_1_0_0'; + + this._shadow = this._avatarImage.getAsset(sprite._Str_3582); + + offsetX = -8; + offsetY = ((this._canStandUp) ? 6 : -3); + } + else + { + sprite._Str_3582 = 'h_std_sd_1_0_0'; + + this._shadow = this._avatarImage.getAsset(sprite._Str_3582); + + offsetX = -17; + offsetY = ((this._canStandUp) ? 10 : -7); + } + + if(this._shadow) + { + sprite.texture = this._shadow.texture; + sprite.offsetX = offsetX; + sprite.offsetY = offsetY; + sprite.alpha = 50; + sprite.relativeDepth = 1; + } + else + { + sprite.visible = false; + } + } + } + else + { + this._shadow = null; + + sprite.visible = false; + } + } + + public getAvatarRenderAsset(name: string): Texture + { + const url = (Nitro.instance.getConfiguration('images.url') + '/additions/' + name + '.png'); + + return this._data ? this._data.getAvatarRendererAsset(url) : null; + } + + public get direction(): number + { + return this._direction; + } + + public get posture(): string + { + return this._posture; + } + + public get angle(): number + { + return this._angle; + } + + public get disposed(): boolean + { + return this._disposed; + } +} diff --git a/src/nitro/room/object/visualization/avatar/AvatarVisualizationData.ts b/src/nitro/room/object/visualization/avatar/AvatarVisualizationData.ts new file mode 100644 index 00000000..1c5df421 --- /dev/null +++ b/src/nitro/room/object/visualization/avatar/AvatarVisualizationData.ts @@ -0,0 +1,61 @@ +import { Texture } from 'pixi.js'; +import { IAssetData } from '../../../../../core/asset/interfaces'; +import { Disposable } from '../../../../../core/common/disposable/Disposable'; +import { IObjectVisualizationData } from '../../../../../room/object/visualization/IRoomObjectVisualizationData'; +import { AvatarScaleType } from '../../../../avatar/enum/AvatarScaleType'; +import { IAvatarEffectListener } from '../../../../avatar/IAvatarEffectListener'; +import { IAvatarImage } from '../../../../avatar/IAvatarImage'; +import { IAvatarImageListener } from '../../../../avatar/IAvatarImageListener'; +import { IAvatarRenderManager } from '../../../../avatar/IAvatarRenderManager'; + +export class AvatarVisualizationData extends Disposable implements IObjectVisualizationData +{ + private _avatarRenderer: IAvatarRenderManager; + + constructor() + { + super(); + } + + public initialize(asset: IAssetData): boolean + { + return true; + } + + public onDispose(): void + { + this._avatarRenderer = null; + } + + public createAvatarImage(figure: string, size: number, gender: string = null, avatarListener: IAvatarImageListener = null, effectListener: IAvatarEffectListener = null): IAvatarImage + { + let avatarImage: IAvatarImage = null; + + if(size > 48) avatarImage = this._avatarRenderer.createAvatarImage(figure, AvatarScaleType.LARGE, gender, avatarListener, effectListener); + else avatarImage = this._avatarRenderer.createAvatarImage(figure, AvatarScaleType.SMALL, gender, avatarListener, effectListener); + + return avatarImage; + } + + public getAvatarRendererAsset(name: string): Texture + { + if(!this._avatarRenderer) return null; + + return this._avatarRenderer.assets.getTexture(name); + } + + public get avatarManager(): IAvatarRenderManager + { + return this._avatarRenderer; + } + + public set avatarManager(renderer: IAvatarRenderManager) + { + this._avatarRenderer = renderer; + } + + public get layerCount(): number + { + return 0; + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/avatar/additions/ExpressionAddition.ts b/src/nitro/room/object/visualization/avatar/additions/ExpressionAddition.ts new file mode 100644 index 00000000..a76b19bd --- /dev/null +++ b/src/nitro/room/object/visualization/avatar/additions/ExpressionAddition.ts @@ -0,0 +1,47 @@ +import { IRoomObjectSprite } from '../../../../../../room/object/visualization/IRoomObjectSprite'; +import { AvatarVisualization } from '../AvatarVisualization'; +import { IExpressionAddition } from './IExpressionAddition'; + +export class ExpressionAddition implements IExpressionAddition +{ + private _id: number; + private _type: number; + private _visualization: AvatarVisualization; + + constructor(id: number, type: number, visualization: AvatarVisualization) + { + this._id = id; + this._type = type; + this._visualization = visualization; + } + + public dispose(): void + { + this._visualization = null; + } + + public update(sprite: IRoomObjectSprite, scale: number): void + { + return; + } + + public animate(sprite: IRoomObjectSprite): boolean + { + return false; + } + + public get id(): number + { + return this._id; + } + + public get type(): number + { + return this._type; + } + + public get visualization(): AvatarVisualization + { + return this._visualization; + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/avatar/additions/ExpressionAdditionFactory.ts b/src/nitro/room/object/visualization/avatar/additions/ExpressionAdditionFactory.ts new file mode 100644 index 00000000..1e5bcd9f --- /dev/null +++ b/src/nitro/room/object/visualization/avatar/additions/ExpressionAdditionFactory.ts @@ -0,0 +1,22 @@ +import { AvatarVisualization } from '../AvatarVisualization'; +import { ExpressionAddition } from './ExpressionAddition'; +import { FloatingHeartAddition } from './FloatingHeartAddition'; +import { IExpressionAddition } from './IExpressionAddition'; + +export class ExpressionAdditionFactory +{ + public static WAVE: number = 1; + public static BLOW: number = 2; + public static LAUGH: number = 3; + public static CRY: number = 4; + public static IDLE: number = 5; + + public static getExpressionAddition(id: number, type: number, visualization: AvatarVisualization): IExpressionAddition + { + switch(type) + { + case this.BLOW: return new FloatingHeartAddition(id, this.BLOW, visualization); + default: return new ExpressionAddition(id, type, visualization); + } + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/avatar/additions/FloatingHeartAddition.ts b/src/nitro/room/object/visualization/avatar/additions/FloatingHeartAddition.ts new file mode 100644 index 00000000..6eef7f99 --- /dev/null +++ b/src/nitro/room/object/visualization/avatar/additions/FloatingHeartAddition.ts @@ -0,0 +1,169 @@ +import { Texture } from 'pixi.js'; +import { IRoomObjectSprite } from '../../../../../../room/object/visualization/IRoomObjectSprite'; +import { Nitro } from '../../../../../Nitro'; +import { AvatarVisualization } from '../AvatarVisualization'; +import { ExpressionAddition } from './ExpressionAddition'; + +export class FloatingHeartAddition extends ExpressionAddition +{ + private static DELAY_BEFORE_ANIMATION: number = 300; + private static STATE_DELAY: number = 0; + private static STATE_FADE_IN: number = 1; + private static STATE_FLOAT: number = 2; + private static STATE_COMPLETE: number = 3; + + private _asset: Texture; + private _startTime: number; + private _delta: number; + private _offsetY: number; + private _scale: number; + private _state: number; + + constructor(id: number, type: number, visualization: AvatarVisualization) + { + super(id, type, visualization); + + this._asset = null; + this._startTime = Nitro.instance.time; + this._delta = 0; + this._offsetY = 0; + this._scale = 0; + this._state = 0; + } + + public update(sprite: IRoomObjectSprite, scale: number): void + { + if(!sprite) return; + + this._scale = scale; + + let additionScale = 64; + let offsetX = 0; + + if(scale < 48) + { + this._asset = this.visualization.getAvatarRenderAsset('user_blowkiss_small'); + + if((this.visualization.angle === 90) || (this.visualization.angle === 270)) + { + offsetX = 0; + } + + else if((this.visualization.angle === 135) || (this.visualization.angle === 180) || (this.visualization.angle === 225)) + { + offsetX = 6; + } + + else offsetX = -6; + + this._offsetY = -38; + + additionScale = 32; + } + else + { + this._asset = this.visualization.getAvatarRenderAsset('user_blowkiss'); + + if((this.visualization.angle === 90) || (this.visualization.angle === 270)) + { + offsetX = -3; + } + + else if((this.visualization.angle === 135) || (this.visualization.angle === 180) || (this.visualization.angle === 225)) + { + offsetX = 22; + } + + else offsetX = -30; + + this._offsetY = -70; + } + + if(this.visualization.posture === 'sit') + { + this._offsetY += (additionScale / 2); + } + + else if(this.visualization.posture === 'lay') + { + this._offsetY += additionScale; + } + + if(this._asset) + { + sprite.texture = this._asset; + sprite.offsetX = offsetX; + sprite.offsetY = this._offsetY; + sprite.relativeDepth = -0.02; + sprite.alpha = 0; + + const delta = this._delta; + + this.animate(sprite); + + this._delta = delta; + } + } + + public animate(sprite: IRoomObjectSprite): boolean + { + if(!sprite) return false; + + if(this._asset) sprite.texture = this._asset; + + if(this._state === FloatingHeartAddition.STATE_DELAY) + { + if((Nitro.instance.time - this._startTime) < FloatingHeartAddition.DELAY_BEFORE_ANIMATION) return false; + + this._state = FloatingHeartAddition.STATE_FADE_IN; + + sprite.alpha = 0; + sprite.visible = true; + + this._delta = 0; + + return true; + } + + if(this._state === FloatingHeartAddition.STATE_FADE_IN) + { + this._delta += 0.1; + + sprite.offsetY = this._offsetY; + sprite.alpha = (Math.pow(this._delta, 0.9) * 255); + + if(this._delta >= 1) + { + sprite.alpha = 255; + + this._delta = 0; + this._state = FloatingHeartAddition.STATE_FLOAT; + } + + return true; + } + + if(this._state === FloatingHeartAddition.STATE_FLOAT) + { + const alpha = Math.pow(this._delta, 0.9); + + this._delta += 0.05; + + const offset = ((this._scale < 48) ? -30 : -40); + + sprite.offsetY = (this._offsetY + (((this._delta < 1) ? alpha : 1) * offset)); + sprite.alpha = ((1 - alpha) * 255); + + if(sprite.alpha <= 0) + { + sprite.visible = false; + + this._state = FloatingHeartAddition.STATE_COMPLETE; + } + + return true; + } + + return false; + } +} diff --git a/src/nitro/room/object/visualization/avatar/additions/FloatingIdleZAddition.ts b/src/nitro/room/object/visualization/avatar/additions/FloatingIdleZAddition.ts new file mode 100644 index 00000000..b926196f --- /dev/null +++ b/src/nitro/room/object/visualization/avatar/additions/FloatingIdleZAddition.ts @@ -0,0 +1,162 @@ +import { Texture } from 'pixi.js'; +import { IRoomObjectSprite } from '../../../../../../room/object/visualization/IRoomObjectSprite'; +import { Nitro } from '../../../../../Nitro'; +import { AvatarVisualization } from '../AvatarVisualization'; +import { IAvatarAddition } from './IAvatarAddition'; + +export class FloatingIdleZAddition implements IAvatarAddition +{ + private static DELAY_BEFORE_ANIMATION: number = 2000; + private static DELAY_PER_FRAME: number = 2000; + private static STATE_DELAY: number = 0; + private static STATE_FRAME_A: number = 1; + private static STATE_FRAME_B: number = 2; + + private _id: number; + private _visualization: AvatarVisualization; + private _asset: Texture; + private _startTime: number; + private _offsetY: number; + private _scale: number; + private _state: number; + + constructor(id: number, visualization: AvatarVisualization) + { + this._id = id; + this._visualization = visualization; + this._asset = null; + this._startTime = Nitro.instance.time; + this._offsetY = 0; + this._scale = 0; + this._state = 0; + } + + public dispose(): void + { + this._visualization = null; + this._asset = null; + } + + private getSpriteAssetName(state: number): string + { + let side = 'left'; + + if((this._visualization.angle === 135) || (this._visualization.angle === 180) || (this._visualization.angle === 225) || (this._visualization.angle === 270)) side = 'right'; + + return ('user_idle_' + side + '_' + state + ((this._scale < 48) ? '_small' : '')); + } + + public update(sprite: IRoomObjectSprite, scale: number): void + { + if(!sprite) return; + + this._scale = scale; + this._asset = this._visualization.getAvatarRenderAsset(this.getSpriteAssetName((this._state === FloatingIdleZAddition.STATE_FRAME_A) ? 1 : 2)); + + let additionScale = 64; + let offsetX = 0; + + if(scale < 48) + { + if((this._visualization.angle === 135) || (this._visualization.angle === 180) || (this._visualization.angle === 225) || (this._visualization.angle === 270)) + { + offsetX = 10; + } + else + { + offsetX = -16; + } + + this._offsetY = -38; + + additionScale = 32; + } + else + { + if((this._visualization.angle === 135) || (this._visualization.angle === 180) || (this._visualization.angle === 225) || (this._visualization.angle === 270)) + { + offsetX = 22; + } + else + { + offsetX = -30; + } + + this._offsetY = -70; + } + + if(this._visualization.posture === 'sit') + { + this._offsetY += (additionScale / 2); + } + + else if(this._visualization.posture === 'lay') + { + this._offsetY += (additionScale - (0.3 * additionScale)); + } + + if(this._asset) + { + sprite.texture = this._asset; + sprite.offsetX = offsetX; + sprite.offsetY = this._offsetY; + sprite.relativeDepth = -0.02; + sprite.alpha = 0; + } + } + + public animate(sprite: IRoomObjectSprite): boolean + { + if(!sprite) return false; + + const totalTimeRunning = Nitro.instance.time; + + if(this._state === FloatingIdleZAddition.STATE_DELAY) + { + if((totalTimeRunning - this._startTime) >= FloatingIdleZAddition.DELAY_BEFORE_ANIMATION) + { + this._state = FloatingIdleZAddition.STATE_FRAME_A; + this._startTime = totalTimeRunning; + this._asset = this._visualization.getAvatarRenderAsset(this.getSpriteAssetName(1)); + } + } + + if(this._state === FloatingIdleZAddition.STATE_FRAME_A) + { + if((totalTimeRunning - this._startTime) >= FloatingIdleZAddition.DELAY_PER_FRAME) + { + this._state = FloatingIdleZAddition.STATE_FRAME_B; + this._startTime = totalTimeRunning; + this._asset = this._visualization.getAvatarRenderAsset(this.getSpriteAssetName(2)); + } + } + + if(this._state === FloatingIdleZAddition.STATE_FRAME_B) + { + if((totalTimeRunning - this._startTime) >= FloatingIdleZAddition.DELAY_PER_FRAME) + { + this._state = FloatingIdleZAddition.STATE_FRAME_A; + this._startTime = totalTimeRunning; + this._asset = this._visualization.getAvatarRenderAsset(this.getSpriteAssetName(1)); + } + } + + if(this._asset) + { + sprite.texture = this._asset; + sprite.alpha = 255; + sprite.visible = true; + } + else + { + sprite.visible = false; + } + + return false; + } + + public get id(): number + { + return this._id; + } +} diff --git a/src/nitro/room/object/visualization/avatar/additions/IAvatarAddition.ts b/src/nitro/room/object/visualization/avatar/additions/IAvatarAddition.ts new file mode 100644 index 00000000..1ff6d84a --- /dev/null +++ b/src/nitro/room/object/visualization/avatar/additions/IAvatarAddition.ts @@ -0,0 +1,9 @@ +import { IRoomObjectSprite } from '../../../../../../room/object/visualization/IRoomObjectSprite'; + +export interface IAvatarAddition +{ + dispose(): void; + update(sprite: IRoomObjectSprite, scale: number): void; + animate(sprite: IRoomObjectSprite): boolean; + id: number; +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/avatar/additions/IExpressionAddition.ts b/src/nitro/room/object/visualization/avatar/additions/IExpressionAddition.ts new file mode 100644 index 00000000..d13225c3 --- /dev/null +++ b/src/nitro/room/object/visualization/avatar/additions/IExpressionAddition.ts @@ -0,0 +1,6 @@ +import { IAvatarAddition } from './IAvatarAddition'; + +export interface IExpressionAddition extends IAvatarAddition +{ + type: number; +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/avatar/additions/MutedBubbleAddition.ts b/src/nitro/room/object/visualization/avatar/additions/MutedBubbleAddition.ts new file mode 100644 index 00000000..95027090 --- /dev/null +++ b/src/nitro/room/object/visualization/avatar/additions/MutedBubbleAddition.ts @@ -0,0 +1,80 @@ +import { Texture } from 'pixi.js'; +import { IRoomObjectSprite } from '../../../../../../room/object/visualization/IRoomObjectSprite'; +import { AvatarVisualization } from '../AvatarVisualization'; +import { IAvatarAddition } from './IAvatarAddition'; + +export class MutedBubbleAddition implements IAvatarAddition +{ + private _id: number; + private _visualization: AvatarVisualization; + private _asset: Texture; + + constructor(id: number, visualization: AvatarVisualization) + { + this._id = id; + this._visualization = visualization; + this._asset = null; + } + + public dispose(): void + { + this._visualization = null; + this._asset = null; + } + + public update(sprite: IRoomObjectSprite, scale: number): void + { + if(!sprite) return; + + let additionScale = 64; + let offsetX = 0; + let offsetY = 0; + + if(scale < 48) + { + this._asset = this._visualization.getAvatarRenderAsset('user_muted_small'); + + additionScale = 32; + offsetX = -12; + offsetY = -66; + } + else + { + this._asset = this._visualization.getAvatarRenderAsset('user_muted'); + + offsetX = -15; + offsetY = -110; + } + + if(this._visualization.posture === 'sit') offsetY += (additionScale / 2); + else if(this._visualization.posture === 'lay') offsetY += scale; + + if(this._asset) + { + sprite.visible = true; + sprite.texture = this._asset; + sprite.offsetX = offsetX; + sprite.offsetY = offsetY; + sprite.relativeDepth = -0.02; + } + else + { + sprite.visible = false; + } + } + + public animate(sprite: IRoomObjectSprite): boolean + { + if(this._asset && sprite) + { + sprite.texture = this._asset; + } + + return false; + } + + public get id(): number + { + return this._id; + } +} diff --git a/src/nitro/room/object/visualization/avatar/additions/NumberBubbleAddition.ts b/src/nitro/room/object/visualization/avatar/additions/NumberBubbleAddition.ts new file mode 100644 index 00000000..abd120cf --- /dev/null +++ b/src/nitro/room/object/visualization/avatar/additions/NumberBubbleAddition.ts @@ -0,0 +1,183 @@ +import { Texture } from 'pixi.js'; +import { IRoomObjectSprite } from '../../../../../../room/object/visualization/IRoomObjectSprite'; +import { AvatarVisualization } from '../AvatarVisualization'; +import { IAvatarAddition } from './IAvatarAddition'; + +export class NumberBubbleAddition implements IAvatarAddition +{ + private _id: number; + private _visualization: AvatarVisualization; + private _asset: Texture; + private _scale: number; + private _number: number; + private _numberValueFadeDirection: number; + private _numberValueMoving: boolean; + private _numberValueMoveCounter: number; + + constructor(id: number, number: number, visualization: AvatarVisualization) + { + this._id = id; + this._visualization = visualization; + this._asset = null; + this._scale = 0; + this._number = number; + this._numberValueFadeDirection = 0; + this._numberValueMoving = false; + this._numberValueMoveCounter = 0; + } + + public dispose(): void + { + this._visualization = null; + this._asset = null; + } + + public update(sprite: IRoomObjectSprite, scale: number): void + { + if(!sprite) return; + + this._scale = scale; + + let additionScale = 64; + let offsetX = 0; + let offsetY = 0; + + if(this._number > 0) + { + if(scale < 48) + { + this._asset = this._visualization.getAvatarRenderAsset('number_' + this._number + '_small'); + + additionScale = 32; + offsetX = -6; + offsetY = -52; + } + else + { + this._asset = this._visualization.getAvatarRenderAsset('number_' + this._number); + + offsetX = -8; + offsetY = -105; + } + + if(this._visualization.posture === 'sit') + { + offsetY += (additionScale / 2); + } + + else if(this._visualization.posture === 'lay') + { + offsetY += scale; + } + + if(this._asset) + { + sprite.visible = true; + sprite.texture = this._asset; + sprite.offsetX = offsetX; + sprite.offsetY = offsetY; + sprite.relativeDepth = -0.01; + sprite.alpha = 0; + + this._numberValueFadeDirection = 1; + this._numberValueMoving = true; + this._numberValueMoveCounter = 0; + } + else + { + sprite.visible = false; + } + } + else + { + if(sprite.visible) this._numberValueFadeDirection = -1; + } + } + + public animate(sprite: IRoomObjectSprite): boolean + { + if(!sprite) return false; + + if(this._asset) + { + sprite.texture = this._asset; + } + + let alpha = sprite.alpha; + let didAnimate = false; + + if(this._numberValueMoving) + { + this._numberValueMoveCounter++; + + if(this._numberValueMoveCounter < 10) return false; + + if(this._numberValueFadeDirection < 0) + { + if(this._scale < 48) + { + sprite.offsetY -= 2; + } + else + { + sprite.offsetY -= 4; + } + } + else + { + let count = 4; + + if(this._scale < 48) count = 8; + + if(!(this._numberValueMoveCounter % count)) + { + sprite.offsetY--; + + didAnimate = true; + } + } + } + + if(this._numberValueFadeDirection > 0) + { + if(alpha < 255) alpha += 32; + + if(alpha >= 255) + { + alpha = 255; + + this._numberValueFadeDirection = 0; + } + + sprite.alpha = alpha; + + return true; + } + + if(this._numberValueFadeDirection < 0) + { + if(alpha >= 0) alpha -= 32; + + if(alpha <= 0) + { + this._numberValueFadeDirection = 0; + this._numberValueMoving = false; + + alpha = 0; + + sprite.visible = false; + } + + sprite.alpha = alpha; + + return true; + } + + return didAnimate; + } + + public get id(): number + { + return this._id; + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/avatar/additions/TypingBubbleAddition.ts b/src/nitro/room/object/visualization/avatar/additions/TypingBubbleAddition.ts new file mode 100644 index 00000000..3210d89a --- /dev/null +++ b/src/nitro/room/object/visualization/avatar/additions/TypingBubbleAddition.ts @@ -0,0 +1,99 @@ +import { Texture } from 'pixi.js'; +import { IRoomObjectSprite } from '../../../../../../room/object/visualization/IRoomObjectSprite'; +import { AvatarVisualization } from '../AvatarVisualization'; +import { IAvatarAddition } from './IAvatarAddition'; + +export class TypingBubbleAddition implements IAvatarAddition +{ + private _id: number; + private _visualization: AvatarVisualization; + private _asset: Texture; + private _relativeDepth: number; + + constructor(id: number, visualization: AvatarVisualization) + { + this._id = id; + this._visualization = visualization; + this._asset = null; + this._relativeDepth = 0; + } + + public dispose(): void + { + this._visualization = null; + this._asset = null; + } + + public update(sprite: IRoomObjectSprite, scale: number): void + { + if(!sprite) return; + + sprite.visible = true; + sprite.relativeDepth = this._relativeDepth; + sprite.alpha = 255; + + let additionScale = 64; + let offsetX = 0; + let offsetY = 0; + + if(scale < 48) + { + this._asset = this._visualization.getAvatarRenderAsset('user_typing_small'); + + offsetX = 3; + offsetY = -42; + + additionScale = 32; + } + else + { + this._asset = this._visualization.getAvatarRenderAsset('user_typing'); + + offsetX = 14; + offsetY = -83; + } + + if(this._visualization.posture === 'sit') + { + offsetY += (additionScale / 2); + } + + else if(this._visualization.posture === 'lay') + { + offsetY += scale; + } + + if(this._asset) + { + sprite.texture = this._asset; + sprite.offsetX = offsetX; + sprite.offsetY = offsetY; + sprite.relativeDepth = (-0.02 + 0); + } + } + + public animate(sprite: IRoomObjectSprite): boolean + { + if(this._asset && sprite) + { + sprite.texture = this._asset; + } + + return false; + } + + public get id(): number + { + return this._id; + } + + public get relativeDepth(): number + { + return this._relativeDepth; + } + + public set relativeDepth(depth: number) + { + this._relativeDepth = depth; + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/data/AnimationData.ts b/src/nitro/room/object/visualization/data/AnimationData.ts new file mode 100644 index 00000000..bd5eefd3 --- /dev/null +++ b/src/nitro/room/object/visualization/data/AnimationData.ts @@ -0,0 +1,191 @@ +import { IAssetVisualAnimation, IAssetVisualAnimationLayer, IAssetVisualAnimationSequenceFrame } from '../../../../../core/asset/interfaces'; +import { AnimationFrame } from './AnimationFrame'; +import { AnimationLayerData } from './AnimationLayerData'; +import { DirectionalOffsetData } from './DirectionalOffsetData'; + +export class AnimationData +{ + private static TRANSITION_TO_ANIMATION_OFFSET: number = 1000000; + private static TRANSITION_FROM_ANIMATION_OFFSET: number = 2000000; + + public static DEFAULT_FRAME_NUMBER: number = 0; + + private _layers: Map; + private _frameCount: number; + private _randomStart: boolean; + private _immediateChanges: number[]; + + constructor() + { + this._layers = new Map(); + this._frameCount = -1; + this._randomStart = false; + this._immediateChanges = null; + } + + public static getTransitionToAnimationId(animationId: number): number + { + return AnimationData.TRANSITION_TO_ANIMATION_OFFSET + animationId; + } + + public static getTransitionFromAnimationId(animationId: number): number + { + return AnimationData.TRANSITION_FROM_ANIMATION_OFFSET + animationId; + } + + public static isTransitionToAnimation(animationId: number): boolean + { + return (animationId >= AnimationData.TRANSITION_TO_ANIMATION_OFFSET) && (animationId < AnimationData.TRANSITION_FROM_ANIMATION_OFFSET); + } + + public static isTransitionFromAnimation(animationId: number): boolean + { + return animationId >= AnimationData.TRANSITION_FROM_ANIMATION_OFFSET; + } + + public dispose(): void + { + for(const layer of this._layers.values()) + { + if(!layer) continue; + + layer.dispose(); + } + + this._layers.clear(); + + this._immediateChanges = null; + } + + public setImmediateChanges(k: number[]): void + { + this._immediateChanges = k; + } + + public isImmediateChange(k: number): boolean + { + if(!this._immediateChanges || (this._immediateChanges.indexOf(k) === -1)) return false; + + return true; + } + + public getStartFrame(direction: number): number + { + if(!this._randomStart) return 0; + + return Math.random() * this._frameCount; + } + + public initialize(k: IAssetVisualAnimation): boolean + { + if(k.randomStart) this._randomStart = true; + + if(k.layers) + { + for(const key in k.layers) + { + const layer = k.layers[key]; + + if(!layer) return false; + + const animationId = parseInt(key); + + const loopCount = (layer.loopCount !== undefined) ? layer.loopCount : 1; + const frameRepeat = (layer.frameRepeat !== undefined) ? layer.frameRepeat : 1; + const isRandom = ((layer.random !== undefined) && (layer.random !== 0)) ? true : false; + + if(!this.addLayer(animationId, loopCount, frameRepeat, isRandom, layer)) return false; + } + } + + return true; + } + + private addLayer(animationId: number, loopCount: number, frameRepeat: number, isRandom: boolean, layer: IAssetVisualAnimationLayer): boolean + { + const layerData = new AnimationLayerData(loopCount, frameRepeat, isRandom); + + if(layer.frameSequences) + { + for(const key in layer.frameSequences) + { + const animationSequence = layer.frameSequences[key]; + + if(!animationSequence) continue; + + const loopCount = (animationSequence.loopCount !== undefined) ? animationSequence.loopCount : 1; + const isSequenceRandom = ((animationSequence.random !== undefined) && (animationSequence.random !== 0)) ? true : false; + + const frame = layerData.addFrameSequence(loopCount, isSequenceRandom); + + if(animationSequence.frames) + { + for(const key in animationSequence.frames) + { + const animationFrame = animationSequence.frames[key]; + + if(!animationFrame) + { + layerData.dispose(); + + return false; + } + + frame.addFrame(animationFrame.id, (animationFrame.x || 0), (animationFrame.y || 0), (animationFrame.randomX || 0), (animationFrame.randomY || 0), this.readDirectionalOffsets(animationFrame)); + } + } + + frame.initialize(); + } + } + + layerData.calculateLength(); + + this._layers.set(animationId, layerData); + + const frameCount: number = layerData.frameCount; + + if(frameCount > this._frameCount) this._frameCount = frameCount; + + return true; + } + + private readDirectionalOffsets(frame: IAssetVisualAnimationSequenceFrame): DirectionalOffsetData + { + let directionalOffset: DirectionalOffsetData = null; + + if(frame && frame.offsets) + { + for(const directionId in frame.offsets) + { + const offset = frame.offsets[directionId]; + + if(!offset) continue; + + if(!directionalOffset) directionalOffset = new DirectionalOffsetData(); + + directionalOffset.setDirection(offset.direction, offset.x, offset.y); + } + } + + return directionalOffset; + } + + public getFrame(direction: number, layerId: number, frameCount: number): AnimationFrame + { + const layer = this._layers.get(layerId); + + if(!layer) return null; + + return layer.getFrame(direction, frameCount); + } + + public getFrameFromSequence(direction: number, layerId: number, sequenceId: number, offset: number, frameCount: number): AnimationFrame + { + const layer = this._layers.get(layerId); + + if(!layer) return null; + + return layer.getFrameFromSequence(direction, sequenceId, offset, frameCount); + } +} diff --git a/src/nitro/room/object/visualization/data/AnimationFrame.ts b/src/nitro/room/object/visualization/data/AnimationFrame.ts new file mode 100644 index 00000000..ad55715a --- /dev/null +++ b/src/nitro/room/object/visualization/data/AnimationFrame.ts @@ -0,0 +1,118 @@ + +export class AnimationFrame +{ + public static FRAME_REPEAT_FOREVER: number = -1; + public static SEQUENCE_NOT_DEFINED: number = -1; + + private static POOL_SIZE_LIMIT: number = 3000; + private static POOL: AnimationFrame[] = []; + + private _id: number; + private _x: number; + private _y: number; + private _repeats: number; + private _frameRepeats: number; + private _remainingFrameRepeats: number; + private _activeSequence: number; + private _activeSequenceOffset: number; + private _isLastFrame: boolean; + private _isRecycled: boolean; + + public static allocate(id: number, x: number, y: number, repeats: number, frameRepeats: number, isLastFrame: boolean, activeSequence: number = -1, sequenceOffset: number = 0): AnimationFrame + { + const frame = (AnimationFrame.POOL.length) ? AnimationFrame.POOL.pop() : new AnimationFrame(); + + if(repeats < 1) repeats = 1; + + if(frameRepeats < 0) frameRepeats = AnimationFrame.FRAME_REPEAT_FOREVER; + + frame._id = id; + frame._x = x || 0; + frame._y = y || 0; + frame._repeats = repeats; + frame._frameRepeats = frameRepeats; + frame._remainingFrameRepeats = frameRepeats; + frame._isLastFrame = isLastFrame; + frame._isRecycled = false; + + if(activeSequence >= 0) + { + frame._activeSequence = activeSequence; + frame._activeSequenceOffset = sequenceOffset; + } + else + { + frame._activeSequence = -1; + frame._activeSequenceOffset = 0; + } + + return frame; + } + + public get id(): number + { + if(this._id >= 0) return this._id; + + return -(this._id) * Math.random(); + } + + public get x(): number + { + return this._x; + } + + public get y(): number + { + return this._y; + } + + public get repeats(): number + { + return this._repeats; + } + + public get frameRepeats(): number + { + return this._frameRepeats; + } + + public get isLastFrame(): boolean + { + return this._isLastFrame; + } + + public get remainingFrameRepeats(): number + { + if(this._frameRepeats < 0) return AnimationFrame.FRAME_REPEAT_FOREVER; + + return this._remainingFrameRepeats; + } + + public set remainingFrameRepeats(k: number) + { + if(k < 0) k = 0; + + if((this._frameRepeats > 0) && (k > this._frameRepeats)) k = this._frameRepeats; + + this._remainingFrameRepeats = k; + } + + public get activeSequence(): number + { + return this._activeSequence; + } + + public get activeSequenceOffset(): number + { + return this._activeSequenceOffset; + } + + public recycle(): void + { + if(this._isRecycled) return; + + this._isRecycled = true; + + if(AnimationFrame.POOL.length < AnimationFrame.POOL_SIZE_LIMIT) AnimationFrame.POOL.push(this); + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/data/AnimationFrameData.ts b/src/nitro/room/object/visualization/data/AnimationFrameData.ts new file mode 100644 index 00000000..008a0d77 --- /dev/null +++ b/src/nitro/room/object/visualization/data/AnimationFrameData.ts @@ -0,0 +1,64 @@ +export class AnimationFrameData +{ + private _id: number = 0; + private _x: number = 0; + private _y: number = 0; + private _randomX: number = 0; + private _randomY: number = 0; + private _repeats: number = 1; + + constructor(id: number, x: number, y: number, randomX: number, randomY: number, repeats: number) + { + this._id = id; + this._x = x; + this._y = y; + this._randomX = randomX; + this._randomY = randomY; + this._repeats = repeats; + } + + public get id(): number + { + return this._id; + } + + public hasDirectionalOffsets(): boolean + { + return false; + } + + public getX(k: number): number + { + return this._x; + } + + public getY(k: number): number + { + return this._y; + } + + public get x(): number + { + return this._x; + } + + public get y(): number + { + return this._x; + } + + public get randomX(): number + { + return this._randomX; + } + + public get randomY(): number + { + return this._randomY; + } + + public get repeats(): number + { + return this._repeats; + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/data/AnimationFrameDirectionalData.ts b/src/nitro/room/object/visualization/data/AnimationFrameDirectionalData.ts new file mode 100644 index 00000000..79f5df91 --- /dev/null +++ b/src/nitro/room/object/visualization/data/AnimationFrameDirectionalData.ts @@ -0,0 +1,33 @@ +import { AnimationFrameData } from './AnimationFrameData'; +import { DirectionalOffsetData } from './DirectionalOffsetData'; + +export class AnimationFrameDirectionalData extends AnimationFrameData +{ + private _directionalOffsets: DirectionalOffsetData; + + constructor(id: number, x: number, y: number, randomX: number, randomY: number, offsets: DirectionalOffsetData, repeats: number) + { + super(id, x, y, randomX, randomY, repeats); + + this._directionalOffsets = offsets; + } + + public hasDirectionalOffsets(): boolean + { + return this._directionalOffsets !== null; + } + + public getX(direction: number): number + { + if(!this._directionalOffsets) return super.getX(direction); + + return this._directionalOffsets.getXOffset(direction, super.getX(direction)); + } + + public getY(direction: number): number + { + if(!this._directionalOffsets) return super.getY(direction); + + return this._directionalOffsets.getYOffset(direction, super.getY(direction)); + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/data/AnimationFrameSequenceData.ts b/src/nitro/room/object/visualization/data/AnimationFrameSequenceData.ts new file mode 100644 index 00000000..b1c2a39e --- /dev/null +++ b/src/nitro/room/object/visualization/data/AnimationFrameSequenceData.ts @@ -0,0 +1,111 @@ +import { AnimationFrameData } from './AnimationFrameData'; +import { AnimationFrameDirectionalData } from './AnimationFrameDirectionalData'; +import { DirectionalOffsetData } from './DirectionalOffsetData'; + +export class AnimationFrameSequenceData +{ + private _frames: AnimationFrameData[]; + private _frameIndexes: number[]; + private _frameRepeats: number[]; + private _isRandom: boolean; + private _loopCount: number; + + constructor(loopCount: number, isRandom: boolean) + { + this._frames = []; + this._frameIndexes = []; + this._frameRepeats = []; + this._isRandom = isRandom; + this._loopCount = (loopCount < 1) ? 1 : loopCount; + } + + public get isRandom(): boolean + { + return this._isRandom; + } + + public get frameCount(): number + { + return (this._frameIndexes.length * this._loopCount); + } + + public dispose(): void + { + this._frames = []; + } + + public initialize(): void + { + let frameIndex: number = (this._frameIndexes.length - 1); + let realIndex = -1; + let nextIndex = 1; + + while(frameIndex >= 0) + { + if(this._frameIndexes[frameIndex] === realIndex) + { + nextIndex++; + } + else + { + realIndex = this._frameIndexes[frameIndex]; + nextIndex = 1; + } + + this._frameRepeats[frameIndex] = nextIndex; + + frameIndex--; + } + } + + public addFrame(id: number, x: number, y: number, randomX: number, randomY: number, directionalOffset: DirectionalOffsetData): void + { + let repeats = 1; + + if(this._frames.length > 0) + { + const frame = this._frames[(this._frames.length - 1)]; + + if((((((((frame.id === id) && (!(frame.hasDirectionalOffsets()))) && (frame.x === x)) && (frame.y === y)) && (frame.randomX === randomX)) && (randomX === 0)) && (frame.randomY === randomY)) && (randomY === 0)) + { + repeats += frame.repeats; + + this._frames.pop(); + } + } + + const frame = (directionalOffset) ? new AnimationFrameDirectionalData(id, x, y, randomX, randomY, directionalOffset, repeats) : new AnimationFrameData(id, x, y, randomX, randomY, repeats); + + this._frames.push(frame); + this._frameIndexes.push((this._frames.length - 1)); + this._frameRepeats.push(1); + } + + public getFrame(frameCount: number): AnimationFrameData + { + if((!this._frames.length || (frameCount < 0)) || (frameCount >= this.frameCount)) return null; + + return this._frames[this._frameIndexes[(frameCount % this._frameIndexes.length)]]; + } + + public getFrameIndex(frameCount: number): number + { + if(((frameCount < 0) || (frameCount >= this.frameCount))) return -1; + + if(this._isRandom) + { + frameCount = Math.round((Math.random() * this._frameIndexes.length)); + + if(frameCount === this._frameIndexes.length) frameCount--; + } + + return frameCount; + } + + public getRepeats(frameCount: number): number + { + if(((frameCount < 0) || (frameCount >= this.frameCount))) return 0; + + return this._frameRepeats[(frameCount % this._frameRepeats.length)]; + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/data/AnimationLayerData.ts b/src/nitro/room/object/visualization/data/AnimationLayerData.ts new file mode 100644 index 00000000..f4fa9308 --- /dev/null +++ b/src/nitro/room/object/visualization/data/AnimationLayerData.ts @@ -0,0 +1,156 @@ +import { AnimationFrame } from './AnimationFrame'; +import { AnimationFrameSequenceData } from './AnimationFrameSequenceData'; + +export class AnimationLayerData +{ + private _frameSequences: AnimationFrameSequenceData[]; + private _frameCount: number; + private _loopCount: number; + private _frameRepeat: number; + private _isRandom: boolean; + + constructor(loopCount: number, frameRepeat: number, isRandom: boolean) + { + this._frameSequences = []; + this._frameCount = -1; + this._loopCount = (loopCount < 0) ? 0 : loopCount; + this._frameRepeat = (frameRepeat < 1) ? 1 : frameRepeat; + this._isRandom = isRandom; + } + + public get frameCount(): number + { + if(this._frameCount < 0) this.calculateLength(); + + return this._frameCount; + } + + public dispose(): void + { + if(!this._frameSequences || !this._frameSequences.length) return; + + for(const sequence of this._frameSequences) + { + if(!sequence) continue; + + sequence.dispose(); + } + + this._frameSequences = []; + } + + public addFrameSequence(loopCount: number, isRandom: boolean): AnimationFrameSequenceData + { + const sequence = new AnimationFrameSequenceData(loopCount, isRandom); + + this._frameSequences.push(sequence); + + return sequence; + } + + public calculateLength(): void + { + this._frameCount = 0; + + for(const sequence of this._frameSequences) + { + if(!sequence) continue; + + this._frameCount += sequence.frameCount; + } + } + + public getFrame(direction: number, frameCount: number): AnimationFrame + { + if(this._frameCount < 1) return null; + + frameCount = (frameCount / this._frameRepeat); + + if(!this._isRandom) + { + const count = Math.floor(frameCount / this._frameCount); + frameCount = Math.floor(frameCount % this._frameCount); + + let doesRepeat = false; + let sequence: AnimationFrameSequenceData = null; + + if(((this._loopCount > 0) && (count >= this._loopCount)) || ((this._loopCount <= 0) && (this._frameCount === 1))) + { + frameCount = (this._frameCount - 1); + doesRepeat = true; + } + + let sequenceFrameCount = 0; + let sequenceId = 0; + + while(sequenceId < this._frameSequences.length) + { + sequence = this._frameSequences[sequenceId]; + + if(sequence) + { + if(frameCount < (sequenceFrameCount + sequence.frameCount)) break; + + sequenceFrameCount += sequence.frameCount; + } + + sequenceId++; + } + + return this.getFrameFromSpecificSequence(direction, sequence, sequenceId, (frameCount - sequenceFrameCount), doesRepeat); + } + + const sequenceId = Math.trunc(this._frameSequences.length * Math.random()); + const sequence = this._frameSequences[sequenceId]; + + if(sequence.frameCount < 1) return null; + + return this.getFrameFromSpecificSequence(direction, sequence, sequenceId, 0, false); + } + + public getFrameFromSequence(direction: number, sequenceId: number, offset: number, frameCount: number): AnimationFrame + { + if((sequenceId < 0) || (sequenceId >= this._frameSequences.length)) return null; + + const sequence = this._frameSequences[sequenceId]; + + if(!sequence) return null; + + if(offset >= sequence.frameCount) return this.getFrame(direction, frameCount); + + return this.getFrameFromSpecificSequence(direction, sequence, sequenceId, offset, false); + } + + private getFrameFromSpecificSequence(direction: number, sequence: AnimationFrameSequenceData, sequenceId: number, offset: number, doesRepeat: boolean): AnimationFrame + { + if(!sequence) return null; + + const frameIndex = sequence.getFrameIndex(offset); + const frame = sequence.getFrame(frameIndex); + + if(!frame) return null; + + let x = frame.getX(direction); + let y = frame.getY(direction); + const randomX = frame.randomX; + const randomY = frame.randomY; + let repeats = frame.repeats; + let isLastFrame = false; + + if(randomX) x = Math.trunc(x + randomX * Math.random()); + if(randomY) y = Math.trunc(y + randomY * Math.random()); + + if(repeats > 1) repeats = sequence.getRepeats(frameIndex); + + let frameRepeats = (this._frameRepeat * repeats); + + if(doesRepeat) frameRepeats = AnimationFrame.FRAME_REPEAT_FOREVER; + + if(!this._isRandom && !sequence.isRandom) + { + if((sequenceId === (this._frameSequences.length - 1)) && (offset === (sequence.frameCount - 1))) isLastFrame = true; + } + + return AnimationFrame.allocate(frame.id, x, y, repeats, frameRepeats, isLastFrame, sequenceId, offset); + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/data/AnimationSizeData.ts b/src/nitro/room/object/visualization/data/AnimationSizeData.ts new file mode 100644 index 00000000..4bce6a21 --- /dev/null +++ b/src/nitro/room/object/visualization/data/AnimationSizeData.ts @@ -0,0 +1,158 @@ +import { IAssetVisualAnimation } from '../../../../../core/asset/interfaces/visualization'; +import { AnimationData } from './AnimationData'; +import { AnimationFrame } from './AnimationFrame'; +import { SizeData } from './SizeData'; + +export class AnimationSizeData extends SizeData +{ + private _animations: Map; + private _animationIds: number[]; + + constructor(layerCount: number, angle: number) + { + super(layerCount, angle); + + this._animations = new Map(); + this._animationIds = []; + } + + public dispose(): void + { + super.dispose(); + + for(const animation of this._animations.values()) + { + if(!animation) continue; + + animation.dispose(); + } + + this._animations.clear(); + + this._animationIds = []; + } + + public defineAnimations(animations: { [index: string]: IAssetVisualAnimation }): boolean + { + if(!animations) return true; + + for(const key in animations) + { + const animation = animations[key]; + + if(!animation) return false; + + let animationId = parseInt(key); + let isTransition = false; + + const transitionTo = animation.transitionTo; + const transitionFrom = animation.transitionFrom; + + if(transitionTo !== undefined) + { + animationId = AnimationData.getTransitionToAnimationId(transitionTo); + isTransition = true; + } + + if(transitionFrom !== undefined) + { + animationId = AnimationData.getTransitionFromAnimationId(transitionFrom); + isTransition = true; + } + + const animationData = this.createAnimationData(); + + if(!animationData.initialize(animation)) + { + animationData.dispose(); + + return false; + } + + const immediateChangeFrom = animation.immediateChangeFrom; + + if(immediateChangeFrom !== undefined) + { + const changes = immediateChangeFrom.split(','); + const changeIds = []; + + for(const change of changes) + { + const changeId = parseInt(change); + + if(changeIds.indexOf(changeId) === -1) changeIds.push(changeId); + } + + animationData.setImmediateChanges(changeIds); + } + + this._animations.set(animationId, animationData); + + if(!isTransition) this._animationIds.push(animationId); + } + + return true; + } + + protected createAnimationData(): AnimationData + { + return new AnimationData(); + } + + public hasAnimation(animationId: number): boolean + { + if(!this._animations.get(animationId)) return false; + + return true; + } + + public getAnimationCount(): number + { + return this._animationIds.length || 0; + } + + public getAnimationId(animationId: number): number + { + const totalAnimations = this.getAnimationCount(); + + if((animationId < 0) || (totalAnimations <= 0)) return 0; + + return this._animationIds[(animationId % totalAnimations)]; + } + + public isImmediateChange(animationId: number, _arg_2: number): boolean + { + const animation = this._animations.get(animationId); + + if(!animation) return false; + + return animation.isImmediateChange(_arg_2); + } + + public getStartFrame(animationId: number, direction: number): number + { + const animation = this._animations.get(animationId); + + if(!animation) return 0; + + return animation.getStartFrame(direction); + } + + public getFrame(animationId: number, direction: number, layerId: number, frameCount: number): AnimationFrame + { + const animation = this._animations.get(animationId); + + if(!animation) return null; + + return animation.getFrame(direction, layerId, frameCount); + } + + public getFrameFromSequence(animationId: number, direction: number, layerId: number, sequenceId: number, offset: number, frameCount: number): AnimationFrame + { + const animation = this._animations.get(animationId); + + if(!animation) return null; + + return animation.getFrameFromSequence(direction, layerId, sequenceId, offset, frameCount); + } +} diff --git a/src/nitro/room/object/visualization/data/AnimationStateData.ts b/src/nitro/room/object/visualization/data/AnimationStateData.ts new file mode 100644 index 00000000..07c42095 --- /dev/null +++ b/src/nitro/room/object/visualization/data/AnimationStateData.ts @@ -0,0 +1,184 @@ +import { AnimationFrame } from './AnimationFrame'; + +export class AnimationStateData +{ + private _animationId: number; + private _animationAfterTransitionId: number; + private _animationOver: boolean; + private _frameCounter: number; + private _frames: AnimationFrame[]; + private _lastFramePlayed: boolean[]; + private _animationPlayed: boolean[]; + private _layerCount: number; + + constructor() + { + this._animationId = -1; + this._animationAfterTransitionId = 0; + this._animationOver = false; + this._frameCounter = 0; + this._frames = []; + this._lastFramePlayed = []; + this._animationPlayed = []; + this._layerCount = 0; + } + + public get animationOver(): boolean + { + return this._animationOver; + } + + public set animationOver(k: boolean) + { + this._animationOver = k; + } + + public get frameCounter(): number + { + return this._frameCounter; + } + + public set frameCounter(k: number) + { + this._frameCounter = k; + } + + public get animationId(): number + { + return this._animationId; + } + + public set animationId(animationId: number) + { + if(animationId === this._animationId) return; + + this._animationId = animationId; + + this.resetAnimationFrames(false); + } + + public get animationAfterTransitionId(): number + { + return this._animationAfterTransitionId; + } + + public set animationAfterTransitionId(k: number) + { + this._animationAfterTransitionId = k; + } + + public dispose(): void + { + this.recycleFrames(); + + this._frames = null; + this._lastFramePlayed = null; + this._animationPlayed = null; + } + + public setLayerCount(k: number): void + { + this._layerCount = k; + + this.resetAnimationFrames(); + } + + public resetAnimationFrames(k: boolean = true): void + { + if(k || (!this._frames)) + { + this.recycleFrames(); + + this._frames = []; + } + + this._lastFramePlayed = []; + this._animationPlayed = []; + this._animationOver = false; + this._frameCounter = 0; + + let layerId = 0; + + while(layerId < this._layerCount) + { + if(k || (this._frames.length <= layerId)) + { + this._frames[layerId] = null; + } + else + { + const frame = this._frames[layerId]; + + if(frame) + { + frame.recycle(); + + this._frames[layerId] = AnimationFrame.allocate(frame.id, frame.x, frame.y, frame.repeats, 0, frame.isLastFrame); + } + } + + this._lastFramePlayed[layerId] = false; + this._animationPlayed[layerId] = false; + + layerId++; + } + } + + private recycleFrames(): void + { + if(!this._frames || !this._frames.length) return; + + for(const frame of this._frames) + { + if(!frame) continue; + + frame.recycle(); + } + } + + public getFrame(layerId: number): AnimationFrame + { + if((layerId < 0) || (layerId >= this._layerCount)) return null; + + return this._frames[layerId]; + } + + public setFrame(layerId: number, frame: AnimationFrame): void + { + if((layerId < 0) || (layerId >= this._layerCount)) return; + + const existingFrame = this._frames[layerId]; + + if(existingFrame) existingFrame.recycle(); + + this._frames[layerId] = frame; + } + + public getAnimationPlayed(layerId: number): boolean + { + if((layerId < 0) || (layerId >= this._layerCount)) return true; + + return this._animationPlayed[layerId]; + } + + public setAnimationPlayed(layerId: number, flag: boolean): void + { + if((layerId < 0) || (layerId >= this._layerCount)) return; + + this._animationPlayed[layerId] = flag; + } + + public getLastFramePlayed(layerId: number): boolean + { + if((layerId < 0) || (layerId >= this._layerCount)) return true; + + return this._lastFramePlayed[layerId]; + } + + public setLastFramePlayed(layerId: number, flag: boolean): void + { + if((layerId < 0) || (layerId >= this._layerCount)) return; + + this._lastFramePlayed[layerId] = flag; + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/data/ColorData.ts b/src/nitro/room/object/visualization/data/ColorData.ts new file mode 100644 index 00000000..05978b57 --- /dev/null +++ b/src/nitro/room/object/visualization/data/ColorData.ts @@ -0,0 +1,43 @@ +export class ColorData +{ + public static DEFAULT_COLOR: number = 0xFFFFFF; + + private _colors: number[]; + + constructor(layerCount: number) + { + this._colors = []; + + this.createColors(layerCount); + } + + private createColors(count: number): void + { + if(!count) return; + + for(let i = 0; i < count; i++) this._colors.push(ColorData.DEFAULT_COLOR); + } + + public dispose(): void + { + this._colors = []; + } + + public getLayerColor(layerId: number): number + { + const existing = this._colors[layerId]; + + if(!existing) return ColorData.DEFAULT_COLOR; + + return existing; + } + + public setColorLayer(layerId: number, color: number): void + { + const existing = this._colors[layerId]; + + if(!existing) return; + + this._colors[layerId] = color; + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/data/DirectionData.ts b/src/nitro/room/object/visualization/data/DirectionData.ts new file mode 100644 index 00000000..86af71fe --- /dev/null +++ b/src/nitro/room/object/visualization/data/DirectionData.ts @@ -0,0 +1,196 @@ +import { LayerData } from './LayerData'; + +export class DirectionData +{ + public static _Str_9471: number = -1; + + private _layers: LayerData[]; + + constructor(layerCount: number) + { + this._layers = []; + + this.createLayers(layerCount); + } + + private createLayers(count: number): void + { + if(!count) return; + + for(let i = 0; i < count; i++) this._layers.push(new LayerData()); + } + + public dispose(): void + { + this._layers = []; + } + + public setFromDirection(directionData: DirectionData): void + { + if(!directionData) return; + + const totalLayers = this.layerCount; + + if(totalLayers !== directionData.layerCount) return; + + for(let i = 0; i < totalLayers; i++) + { + const localLayer = this.getLayer(i); + const directionLayer = directionData.getLayer(i); + + if(!localLayer) continue; + + localLayer.setFromLayer(directionLayer); + } + } + + public getLayer(layerId: number): LayerData + { + const existing = this._layers[layerId]; + + if(!existing) return null; + + return existing; + } + + public getLayerTag(layerId: number): string + { + const existing = this.getLayer(layerId); + + if(!existing) return LayerData.DEFAULT_TAG; + + return existing.tag; + } + + public setLayerTag(layerId: number, tag: string): void + { + const existing = this.getLayer(layerId); + + if(!existing) return; + + existing.tag = tag; + } + + public getLayerInk(layerId: number): number + { + const existing = this.getLayer(layerId); + + if(!existing) return LayerData.DEFAULT_INK; + + return existing.ink; + } + + public setLayerInk(layerId: number, ink: number): void + { + const existing = this.getLayer(layerId); + + if(!existing) return; + + if(isNaN(ink)) return; + + existing.ink = ink; + } + + public getLayerAlpha(layerId: number): number + { + const existing = this.getLayer(layerId); + + if(!existing) return LayerData.DEFAULT_ALPHA; + + return existing.alpha; + } + + public setLayerAlpha(layerId: number, alpha: number): void + { + const existing = this.getLayer(layerId); + + if(!existing) return; + + if(isNaN(alpha)) return; + + existing.alpha = alpha; + } + + public getLayerIgnoreMouse(layerId: number): boolean + { + const existing = this.getLayer(layerId); + + if(!existing) return LayerData.DEFAULT_IGNORE_MOUSE; + + return existing.ignoreMouse; + } + + public setLayerIgnoreMouse(layerId: number, flag: boolean): void + { + const existing = this.getLayer(layerId); + + if(!existing) return; + + existing.ignoreMouse = flag || false; + } + + public getLayerXOffset(layerId: number): number + { + const existing = this.getLayer(layerId); + + if(!existing) return LayerData.DEFAULT_XOFFSET; + + return existing.xOffset; + } + + public setLayerXOffset(layerId: number, offset: number): void + { + const existing = this.getLayer(layerId); + + if(!existing) return; + + if(isNaN(offset)) return; + + existing.xOffset = offset; + } + + public getLayerYOffset(layerId: number): number + { + const existing = this.getLayer(layerId); + + if(!existing) return LayerData.DEFAULT_YOFFSET; + + return existing.yOffset; + } + + public setLayerYOffset(layerId: number, offset: number): void + { + const existing = this.getLayer(layerId); + + if(!existing) return; + + if(isNaN(offset)) return; + + existing.yOffset = offset; + } + + public getLayerZOffset(layerId: number): number + { + const existing = this.getLayer(layerId); + + if(!existing) return LayerData.DEFAULT_ZOFFSET; + + return existing.zOffset; + } + + public setLayerZOffset(layerId: number, offset: number): void + { + const existing = this.getLayer(layerId); + + if(!existing) return; + + if(isNaN(offset)) return; + + existing.zOffset = offset; + } + + public get layerCount(): number + { + return this._layers.length; + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/data/DirectionalOffsetData.ts b/src/nitro/room/object/visualization/data/DirectionalOffsetData.ts new file mode 100644 index 00000000..59018177 --- /dev/null +++ b/src/nitro/room/object/visualization/data/DirectionalOffsetData.ts @@ -0,0 +1,35 @@ +export class DirectionalOffsetData +{ + private _offsetX: Map; + private _offsetY: Map; + + constructor() + { + this._offsetX = new Map(); + this._offsetY = new Map(); + } + + public getXOffset(direction: number, defaultX: number): number + { + const existing = this._offsetX.get(direction); + + if(existing === undefined || existing === null) return defaultX; + + return existing; + } + + public getYOffset(direction: number, defaultY: number): number + { + const existing = this._offsetY.get(direction); + + if(existing === undefined || existing === null) return defaultY; + + return existing; + } + + public setDirection(direction: number, offsetX: number, offsetY: number): void + { + this._offsetX.set(direction, offsetX); + this._offsetY.set(direction, offsetY); + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/data/LayerData.ts b/src/nitro/room/object/visualization/data/LayerData.ts new file mode 100644 index 00000000..e4b77a42 --- /dev/null +++ b/src/nitro/room/object/visualization/data/LayerData.ts @@ -0,0 +1,120 @@ +import { BLEND_MODES } from 'pixi.js'; + +export class LayerData +{ + public static DEFAULT_COUNT: number = 0; + public static DEFAULT_DIRECTION: number = 0; + public static DEFAULT_TAG: string = ''; + public static DEFAULT_INK: number = BLEND_MODES.NORMAL; + public static DEFAULT_ALPHA: number = 255; + public static DEFAULT_IGNORE_MOUSE: boolean = false; + public static DEFAULT_XOFFSET: number = 0; + public static DEFAULT_YOFFSET: number = 0; + public static DEFAULT_ZOFFSET: number = 0; + + public static ADD_INK: number = BLEND_MODES.ADD; + public static SUBTRACT_INK: number = BLEND_MODES.NORMAL; + public static DARKEN_INK: number = BLEND_MODES.NORMAL; + + private _tag: string; + private _ink: number; + private _alpha: number; + private _ignoreMouse: boolean; + private _xOffset: number; + private _yOffset: number; + private _zOffset: number; + + constructor() + { + this._tag = LayerData.DEFAULT_TAG; + this._ink = LayerData.DEFAULT_INK; + this._alpha = LayerData.DEFAULT_ALPHA; + this._ignoreMouse = LayerData.DEFAULT_IGNORE_MOUSE; + this._xOffset = LayerData.DEFAULT_XOFFSET; + this._yOffset = LayerData.DEFAULT_YOFFSET; + this._zOffset = LayerData.DEFAULT_ZOFFSET; + } + + public setFromLayer(layer: LayerData): void + { + if(!layer) return; + + this._tag = layer.tag; + this._ink = layer.ink; + this._alpha = layer.alpha; + this._ignoreMouse = layer.ignoreMouse; + this._xOffset = layer.xOffset; + this._yOffset = layer.yOffset; + this._zOffset = layer.zOffset; + } + + public get tag(): string + { + return this._tag; + } + + public set tag(tag: string) + { + this._tag = tag; + } + + public get ink(): number + { + return this._ink; + } + + public set ink(ink: number) + { + this._ink = ink; + } + + public get alpha(): number + { + return this._alpha; + } + + public set alpha(alpha: number) + { + this._alpha = alpha; + } + + public get ignoreMouse(): boolean + { + return this._ignoreMouse; + } + + public set ignoreMouse(flag: boolean) + { + this._ignoreMouse = flag; + } + + public get xOffset(): number + { + return this._xOffset; + } + + public set xOffset(offset: number) + { + this._xOffset = offset; + } + + public get yOffset(): number + { + return this._yOffset; + } + + public set yOffset(offset: number) + { + this._yOffset = offset; + } + + public get zOffset(): number + { + return this._zOffset; + } + + public set zOffset(offset: number) + { + this._zOffset = offset; + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/data/PetSizeData.ts b/src/nitro/room/object/visualization/data/PetSizeData.ts new file mode 100644 index 00000000..4fae2e71 --- /dev/null +++ b/src/nitro/room/object/visualization/data/PetSizeData.ts @@ -0,0 +1,143 @@ +import { IAssetGesture, IAssetPosture } from '../../../../../core/asset/interfaces/visualization'; +import { AnimationSizeData } from './AnimationSizeData'; + +export class PetSizeData extends AnimationSizeData +{ + public static DEFAULT: number = -1; + + private _posturesToAnimations: Map; + private _gesturesToAnimations: Map; + private _defaultPosture: string; + + constructor(layerCount: number, angle: number) + { + super(layerCount, angle); + + this._posturesToAnimations = new Map(); + this._gesturesToAnimations = new Map(); + this._defaultPosture = null; + } + + public processPostures(postures: { [index: string]: IAssetPosture }): boolean + { + if(!postures) return false; + + for(const key in postures) + { + const posture = postures[key]; + + if(!posture) continue; + + if(this._posturesToAnimations.get(posture.id)) continue; + + if(this._defaultPosture === null) this._defaultPosture = posture.id; + + this._posturesToAnimations.set(posture.id, posture.animationId); + } + + if(this._posturesToAnimations.get(this._defaultPosture) === undefined) return false; + + return true; + } + + public processGestures(gestures: { [index: string]: IAssetGesture }): boolean + { + if(!gestures) return false; + + for(const key in gestures) + { + const gesture = gestures[key]; + + if(!gesture) continue; + + if(this._gesturesToAnimations.get(gesture.id)) continue; + + this._gesturesToAnimations.set(gesture.id, gesture.animationId); + } + + return true; + } + + public postureToAnimation(posture: string): number + { + if(!this._posturesToAnimations.get(posture)) posture = this._defaultPosture; + + return this._posturesToAnimations.get(posture); + } + + public _Str_18284(k: string): boolean + { + if(k === 'ded') return true; + + return false; + } + + public gestureToAnimation(gesture: string): number + { + if(!this._gesturesToAnimations.get(gesture)) return PetSizeData.DEFAULT; + + return this._gesturesToAnimations.get(gesture); + } + + public _Str_14207(k: number, _arg_2: boolean): string + { + if((k >= 0) && (k < this._posturesToAnimations.size)) + { + const keys = this._posturesToAnimations.keys(); + + for(;;) + { + const key = keys.next(); + + if(key.done) return null; + + if(k <= 0) return key.value; + + --k; + } + } + + return (_arg_2) ? this._defaultPosture : null; + } + + public _Str_17844(index: number): string + { + if((index >= 0) && (index < this._gesturesToAnimations.size)) + { + const keys = this._gesturesToAnimations.keys(); + + for(;;) + { + const key = keys.next(); + + if(key.done) return null; + + if(index <= 0) return key.value; + + --index; + } + } + + return null; + } + + public _Str_17976(k: number): string + { + for(const _local_2 of this._gesturesToAnimations.keys()) + { + if(this._gesturesToAnimations.get(_local_2) === k) return _local_2; + } + + return null; + } + + public get totalPostures(): number + { + return this._posturesToAnimations.size; + } + + public get totalGestures(): number + { + return this._gesturesToAnimations.size; + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/data/SizeData.ts b/src/nitro/room/object/visualization/data/SizeData.ts new file mode 100644 index 00000000..ba9e942d --- /dev/null +++ b/src/nitro/room/object/visualization/data/SizeData.ts @@ -0,0 +1,284 @@ +import { IAssetColor, IAssetVisualizationDirection, IAssetVisualizationLayer } from '../../../../../core/asset/interfaces/visualization'; +import { SpriteUtilities } from '../../../../../room/utils/SpriteUtilities'; +import { ColorData } from './ColorData'; +import { DirectionData } from './DirectionData'; +import { LayerData } from './LayerData'; + +export class SizeData +{ + public static MAX_LAYERS: number = 26; + + private _layerCount: number; + private _angle: number; + + private _defaultDirection: DirectionData; + private _directions: Map; + private _colors: ColorData[]; + private _lastDirectionData: DirectionData; + private _lastDirection: number; + + constructor(layerCount: number, angle: number) + { + this._layerCount = ((layerCount < 0) ? 0 : ((layerCount > SizeData.MAX_LAYERS) ? SizeData.MAX_LAYERS : layerCount)); + this._angle = angle < 1 ? 1 : angle > 360 ? 360 : angle; + + this._defaultDirection = new DirectionData(this._layerCount); + this._directions = new Map(); + this._colors = []; + this._lastDirectionData = null; + this._lastDirection = -1; + } + + public dispose(): void + { + if(this._defaultDirection) this._defaultDirection.dispose(); + + for(const direction of this._directions.values()) + { + if(!direction) continue; + + direction.dispose(); + } + + for(const color of this._colors) + { + if(!color) continue; + + color.dispose(); + } + + this.reset(); + } + + protected reset(): void + { + this._defaultDirection = null; + this._colors = []; + this._lastDirectionData = null; + this._lastDirection = -1; + + this._directions.clear(); + } + + public processLayers(layers: { [index: string]: IAssetVisualizationLayer }): boolean + { + if(!layers) return false; + + return this.setDirectionLayers(this._defaultDirection, layers); + } + + public processDirections(directions: { [index: string]: IAssetVisualizationDirection }): boolean + { + if(!directions) return false; + + for(const key in directions) + { + const direction = directions[key]; + + if(!direction) continue; + + const directionNumber = parseInt(key); + + if(this._directions.get(directionNumber)) return false; + + const directionData = new DirectionData(this._layerCount); + + directionData.setFromDirection(this._defaultDirection); + + this.setDirectionLayers(directionData, direction.layers); + + this._directions.set(directionNumber, directionData); + + this._lastDirectionData = null; + this._lastDirection = -1; + } + + return true; + } + + public processColors(colors: { [index: string]: IAssetColor }): boolean + { + if(!colors) return false; + + for(const key in colors) + { + const color = colors[key]; + + if(!color) continue; + + const colorNumber = parseInt(key); + + if(this._colors[colorNumber]) return false; + + const colorData = new ColorData(this._layerCount); + + for(const layer in color.layers) + { + const colorLayer = color.layers[layer]; + + if(!colorLayer) continue; + + const layerId = parseInt(layer); + const colorId = colorLayer.color; + + colorData.setColorLayer(layerId, colorId); + } + + this._colors[colorNumber] = colorData; + } + + return true; + } + + private setDirectionLayers(directionData: DirectionData, layers: { [index: string]: IAssetVisualizationLayer }): boolean + { + if(!directionData || !layers) return false; + + for(const key in layers) + { + const layer = layers[key]; + + if(!layer) continue; + + const layerId = parseInt(key); + + if(layerId < 0 || (layerId >= this._layerCount)) return false; + + if(layer.ink !== undefined) directionData.setLayerInk(layerId, SpriteUtilities.inkToBlendMode(layer.ink)); + + if(layer.tag !== undefined) directionData.setLayerTag(layerId, layer.tag); + + if(layer.alpha !== undefined) directionData.setLayerAlpha(layerId, layer.alpha); + + if(layer.ignoreMouse !== undefined) directionData.setLayerIgnoreMouse(layerId, layer.ignoreMouse); + + if(layer.x !== undefined) directionData.setLayerXOffset(layerId, layer.x); + + if(layer.y !== undefined) directionData.setLayerYOffset(layerId, layer.y); + + if(layer.z !== undefined) directionData.setLayerZOffset(layerId, (layer.z / -1000)); + } + + return true; + } + + public getValidDirection(direction: number): number + { + const existing = this._directions.get(direction); + + if(existing) return direction; + + direction = (((direction % 360) + 360) % 360); + + let currentAngle = -1; + let validDirection = -1; + + for(const key of this._directions.keys()) + { + let angle = ((((key * this._angle) - direction) + 360) % 360); + + if(angle > 180) angle = (360 - angle); + + if((angle < currentAngle) || (currentAngle < 0)) + { + currentAngle = angle; + validDirection = key; + } + } + + if(validDirection >= 0) return Math.trunc(validDirection); + + return 0; + } + + public getDirectionData(direction: number): DirectionData + { + if(direction === this._lastDirection && this._lastDirectionData) return this._lastDirectionData; + + let directionData = this._directions.get(direction); + + if(!directionData) directionData = this._defaultDirection; + + this._lastDirection = direction; + this._lastDirectionData = directionData; + + return this._lastDirectionData; + } + + public getLayerTag(direction: number, layerId: number): string + { + const directionData = this.getDirectionData(direction); + + if(!directionData) return LayerData.DEFAULT_TAG; + + return directionData.getLayerTag(layerId); + } + + public getLayerInk(direction: number, layerId: number): number + { + const directionData = this.getDirectionData(direction); + + if(!directionData) return LayerData.DEFAULT_INK; + + return directionData.getLayerInk(layerId); + } + + public getLayerAlpha(direction: number, layerId: number): number + { + const directionData = this.getDirectionData(direction); + + if(!directionData) return LayerData.DEFAULT_ALPHA; + + return directionData.getLayerAlpha(layerId); + } + + public getLayerColor(layerId: number, colorId: number): number + { + const existing = this._colors[colorId] as ColorData; + + if(!existing) return ColorData.DEFAULT_COLOR; + + return existing.getLayerColor(layerId); + } + + public getLayerIgnoreMouse(direction: number, layerId: number): boolean + { + const directionData = this.getDirectionData(direction); + + if(!directionData) return LayerData.DEFAULT_IGNORE_MOUSE; + + return directionData.getLayerIgnoreMouse(layerId); + } + + public getLayerXOffset(direction: number, layerId: number): number + { + const directionData = this.getDirectionData(direction); + + if(!directionData) return LayerData.DEFAULT_XOFFSET; + + return directionData.getLayerXOffset(layerId); + } + + public getLayerYOffset(direction: number, layerId: number): number + { + const directionData = this.getDirectionData(direction); + + if(!directionData) return LayerData.DEFAULT_YOFFSET; + + return directionData.getLayerYOffset(layerId); + } + + public getLayerZOffset(direction: number, layerId: number): number + { + const directionData = this.getDirectionData(direction); + + if(!directionData) return LayerData.DEFAULT_ZOFFSET; + + return directionData.getLayerZOffset(layerId); + } + + public get layerCount(): number + { + return this._layerCount; + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/furniture/FurnitureAnimatedVisualization.ts b/src/nitro/room/object/visualization/furniture/FurnitureAnimatedVisualization.ts new file mode 100644 index 00000000..a2d4c115 --- /dev/null +++ b/src/nitro/room/object/visualization/furniture/FurnitureAnimatedVisualization.ts @@ -0,0 +1,407 @@ +import { IObjectVisualizationData } from '../../../../../room/object/visualization/IRoomObjectVisualizationData'; +import { RoomObjectVariable } from '../../RoomObjectVariable'; +import { RoomObjectVisualizationType } from '../../RoomObjectVisualizationType'; +import { AnimationData } from '../data/AnimationData'; +import { AnimationFrame } from '../data/AnimationFrame'; +import { AnimationStateData } from '../data/AnimationStateData'; +import { FurnitureAnimatedVisualizationData } from './FurnitureAnimatedVisualizationData'; +import { FurnitureVisualization } from './FurnitureVisualization'; + +export class FurnitureAnimatedVisualization extends FurnitureVisualization +{ + private static FRAME_INCREASE_AMOUNT: number = 1; + + public static TYPE: string = RoomObjectVisualizationType.FURNITURE_ANIMATED; + public static DEFAULT_ANIMATION_ID: number = 0; + + protected _data: FurnitureAnimatedVisualizationData; + + protected _state: number; + private _animationData: AnimationStateData; + private _animationScale: number; + private _animationChangeTime: number; + private _animatedLayerCount: number; + private _directionChanged: boolean; + + constructor() + { + super(); + + this._state = -1; + this._animationData = new AnimationStateData(); + this._animationScale = 0; + this._animationChangeTime = 0; + this._animatedLayerCount = 0; + this._directionChanged = false; + } + + public initialize(data: IObjectVisualizationData): boolean + { + if(!(data instanceof FurnitureAnimatedVisualizationData)) return false; + + return super.initialize(data); + } + + public dispose(): void + { + super.dispose(); + + if(this._animationData) + { + this._animationData.dispose(); + + this._animationData = null; + } + } + + protected get animatedLayerCount(): number + { + return this._animatedLayerCount; + } + + public get animationId(): number + { + return this._animationData.animationId; + } + + protected getAnimationId(animationData: AnimationStateData): number + { + if((this.animationId !== FurnitureAnimatedVisualization.DEFAULT_ANIMATION_ID) && this._data.hasAnimation(this._animationScale, this.animationId)) return this.animationId; + + return FurnitureAnimatedVisualization.DEFAULT_ANIMATION_ID; + } + + protected updateObject(scale: number, direction: number): boolean + { + if(super.updateObject(scale, direction)) + { + const state = this.object.getState(0); + + if(state !== this._state) + { + this.setAnimation(state); + + this._state = state; + + this._animationChangeTime = (this.object.model.getValue(RoomObjectVariable.FURNITURE_STATE_UPDATE_TIME) || 0); + } + + return true; + } + + return false; + } + + protected updateModel(scale: number): boolean + { + if(super.updateModel(scale)) + { + if(this.usesAnimationResetting()) + { + const updateTime = this.object.model.getValue(RoomObjectVariable.FURNITURE_STATE_UPDATE_TIME); + + if(updateTime > this._animationChangeTime) + { + this._animationChangeTime = updateTime; + + this.setAnimation(this._state); + } + } + + const state = this.object.model.getValue(RoomObjectVariable.FURNITURE_AUTOMATIC_STATE_INDEX); + + if(!isNaN(state)) + { + const animationId = this._data.getAnimationId(this._animationScale, state); + + this.setAnimation(animationId); + } + + return true; + } + + return false; + } + + private isPlayingTransition(animationData: AnimationStateData, animationId: number): boolean + { + if(!AnimationData.isTransitionFromAnimation(animationData.animationId) && !AnimationData.isTransitionToAnimation(animationData.animationId)) return false; + + if(animationId !== animationData.animationAfterTransitionId) return false; + + if(animationData.animationOver) return false; + + return true; + } + + private getCurrentState(animationData: AnimationStateData): number + { + const animationId = animationData.animationId; + + if(!AnimationData.isTransitionFromAnimation(animationId) && !AnimationData.isTransitionToAnimation(animationId)) return animationId; + + return animationData.animationAfterTransitionId; + } + + protected setAnimation(animationId: number): void + { + if(!this._data) return; + + this.setSubAnimation(this._animationData, animationId, (this._state >= 0)); + } + + protected setSubAnimation(animationData: AnimationStateData, animationId: number, _arg_3: boolean = true): boolean + { + const currentAnimation = animationData.animationId; + + if(_arg_3) + { + if(this.isPlayingTransition(animationData, animationId)) return false; + + const state = this.getCurrentState(animationData); + + if(animationId !== state) + { + if(!this._data.isImmediateChange(this._animationScale, animationId, state)) + { + let transition = AnimationData.getTransitionFromAnimationId(state); + + if(this._data.hasAnimation(this._animationScale, transition)) + { + animationData.animationAfterTransitionId = animationId; + animationId = transition; + } + else + { + transition = AnimationData.getTransitionToAnimationId(animationId); + + if(this._data.hasAnimation(this._animationScale, transition)) + { + animationData.animationAfterTransitionId = animationId; + animationId = transition; + } + } + } + } + else + { + if(AnimationData.isTransitionFromAnimation(animationData.animationId)) + { + const transition = AnimationData.getTransitionToAnimationId(animationId); + + if(this._data.hasAnimation(this._animationScale, transition)) + { + animationData.animationAfterTransitionId = animationId; + animationId = transition; + } + } + + else if(!AnimationData.isTransitionToAnimation(animationData.animationId)) + { + if(this.usesAnimationResetting()) + { + const transition = AnimationData.getTransitionFromAnimationId(state); + + if(this._data.hasAnimation(this._animationScale, transition)) + { + animationData.animationAfterTransitionId = animationId; + animationId = transition; + } + else + { + const transition = AnimationData.getTransitionToAnimationId(animationId); + + if(this._data.hasAnimation(this._animationScale, transition)) + { + animationData.animationAfterTransitionId = animationId; + animationId = transition; + } + } + } + } + } + } + + if(currentAnimation !== animationId) + { + animationData.animationId = animationId; + + return true; + } + + return false; + } + + protected getLastFramePlayed(layerId: number): boolean + { + return this._animationData.getLastFramePlayed(layerId); + } + + protected resetAllAnimationFrames(): void + { + if(!this._animationData) return; + + this._animationData.setLayerCount(this._animatedLayerCount); + } + + protected updateAnimation(scale: number): number + { + if(!this._data) return 0; + + if(scale !== this._animationScale) + { + this._animationScale = scale; + this._animatedLayerCount = this._data.getLayerCount(scale); + + this.resetAllAnimationFrames(); + } + + const update = this.updateAnimations(scale); + + this._directionChanged = false; + + return update; + } + + protected updateAnimations(scale: number): number + { + if(this._animationData.animationOver && !this._directionChanged) return 0; + + const update = this.updateFramesForAnimation(this._animationData, scale); + + if(this._animationData.animationOver) + { + if((AnimationData.isTransitionFromAnimation(this._animationData.animationId)) || (AnimationData.isTransitionToAnimation(this._animationData.animationId))) + { + this.setAnimation(this._animationData.animationAfterTransitionId); + this._animationData.animationOver = false; + } + } + + return update; + } + + protected updateFramesForAnimation(animationData: AnimationStateData, scale: number): number + { + if(animationData.animationOver && !this._directionChanged) return 0; + + const animationId = this.getAnimationId(animationData); + let frameCount = animationData.frameCounter; + + if(!frameCount) frameCount = this._data.getStartFrame(scale, animationId, this._direction); + + frameCount += FurnitureAnimatedVisualization.FRAME_INCREASE_AMOUNT; + animationData.frameCounter = frameCount; + animationData.animationOver = true; + + let animationPlayed = false; + let layerId = (this._animatedLayerCount - 1); + let update = 0; + let layerUpdate = (1 << (this._animatedLayerCount - 1)); + + while(layerId >= 0) + { + let sequenceId = 0; + + animationPlayed = animationData.getAnimationPlayed(layerId); + + if(!animationPlayed || this._directionChanged) + { + let lastFramePlayed = animationData.getLastFramePlayed(layerId); + let frame = animationData.getFrame(layerId); + + if(frame) + { + if(frame.isLastFrame && (frame.remainingFrameRepeats <= FurnitureAnimatedVisualization.FRAME_INCREASE_AMOUNT)) + { + lastFramePlayed = true; + } + } + + if((this._directionChanged || !frame) || ((frame.remainingFrameRepeats >= 0) && ((frame.remainingFrameRepeats = (frame.remainingFrameRepeats - FurnitureAnimatedVisualization.FRAME_INCREASE_AMOUNT)) <= 0))) + { + sequenceId = AnimationFrame.SEQUENCE_NOT_DEFINED; + + if(frame) sequenceId = frame.activeSequence; + + if(sequenceId === AnimationFrame.SEQUENCE_NOT_DEFINED) + { + frame = this._data.getFrame(scale, animationId, this._direction, layerId, frameCount); + } + else + { + frame = this._data.getFrameFromSequence(scale, animationId, this._direction, layerId, sequenceId, (frame.activeSequenceOffset + frame.repeats), frameCount); + } + + animationData.setFrame(layerId, frame); + + update = (update | layerUpdate); + } + + if(!frame || (frame.remainingFrameRepeats == AnimationFrame.FRAME_REPEAT_FOREVER)) + { + lastFramePlayed = true; + animationPlayed = true; + } + else + { + animationData.animationOver = false; + } + + animationData.setLastFramePlayed(layerId, lastFramePlayed); + animationData.setAnimationPlayed(layerId, animationPlayed); + } + + layerUpdate = (layerUpdate >> 1); + + layerId--; + } + + return update; + } + + protected getFrameNumber(scale: number, layerId: number): number + { + const currentFrame = this._animationData.getFrame(layerId); + + if(!currentFrame) return super.getFrameNumber(scale, layerId); + + return currentFrame.id; + } + + protected getLayerXOffset(scale: number, direction: number, layerId: number): number + { + const offset = super.getLayerXOffset(scale, direction, layerId); + + const currentFrame = this._animationData.getFrame(layerId); + + if(!currentFrame) return offset; + + return (offset + currentFrame.x); + } + + protected getLayerYOffset(scale: number, direction: number, layerId: number): number + { + const offset = super.getLayerYOffset(scale, direction, layerId); + + const currentFrame = this._animationData.getFrame(layerId); + + if(!currentFrame) return offset; + + return (offset + currentFrame.y); + } + + protected usesAnimationResetting(): boolean + { + return false; + } + + protected setDirection(direction: number): void + { + if(this._direction === direction) return; + + super.setDirection(direction); + + this._directionChanged = true; + } +} diff --git a/src/nitro/room/object/visualization/furniture/FurnitureAnimatedVisualizationData.ts b/src/nitro/room/object/visualization/furniture/FurnitureAnimatedVisualizationData.ts new file mode 100644 index 00000000..293338fd --- /dev/null +++ b/src/nitro/room/object/visualization/furniture/FurnitureAnimatedVisualizationData.ts @@ -0,0 +1,92 @@ +import { AnimationFrame } from '../data/AnimationFrame'; +import { AnimationSizeData } from '../data/AnimationSizeData'; +import { SizeData } from '../data/SizeData'; +import { FurnitureVisualizationData } from './FurnitureVisualizationData'; + +export class FurnitureAnimatedVisualizationData extends FurnitureVisualizationData +{ + protected createSizeData(scale: number, layerCount: number, angle: number): SizeData + { + return new AnimationSizeData(layerCount, angle); + } + + protected processVisualElement(sizeData: SizeData, key: string, data: any): boolean + { + if(!sizeData || !key || !data) return false; + + switch(key) + { + case 'animations': + if(!(sizeData instanceof AnimationSizeData) || !sizeData.defineAnimations(data)) return false; + break; + default: + if(!super.processVisualElement(sizeData, key, data)) return false; + break; + } + + return true; + } + + public hasAnimation(scale: number, animationId: number): boolean + { + const size = this.getSizeData(scale) as AnimationSizeData; + + if(!size) return null; + + return size.hasAnimation(animationId); + } + + public getAnimationCount(scale: number): number + { + const size = this.getSizeData(scale) as AnimationSizeData; + + if(!size) return null; + + return size.getAnimationCount(); + } + + public getAnimationId(scale: number, animationId: number): number + { + const size = this.getSizeData(scale) as AnimationSizeData; + + if(!size) return null; + + return size.getAnimationId(animationId); + } + + public isImmediateChange(scale: number, animationId: number, _arg_3: number): boolean + { + const size = this.getSizeData(scale) as AnimationSizeData; + + if(!size) return null; + + return size.isImmediateChange(animationId, _arg_3); + } + + public getStartFrame(scale: number, animationId: number, direction: number): number + { + const size = this.getSizeData(scale) as AnimationSizeData; + + if(!size) return null; + + return size.getStartFrame(animationId, direction); + } + + public getFrame(scale: number, animationId: number, direction: number, layerId: number, frameCount: number): AnimationFrame + { + const size = this.getSizeData(scale) as AnimationSizeData; + + if(!size) return null; + + return size.getFrame(animationId, direction, layerId, frameCount); + } + + public getFrameFromSequence(scale: number, animationId: number, direction: number, layerId: number, sequenceId: number, offset: number, frameCount: number):AnimationFrame + { + const size = this.getSizeData(scale) as AnimationSizeData; + + if(!size) return null; + + return size.getFrameFromSequence(animationId, direction, layerId, sequenceId, offset, frameCount); + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/furniture/FurnitureBBVisualization.ts b/src/nitro/room/object/visualization/furniture/FurnitureBBVisualization.ts new file mode 100644 index 00000000..0c8b3078 --- /dev/null +++ b/src/nitro/room/object/visualization/furniture/FurnitureBBVisualization.ts @@ -0,0 +1,19 @@ +import { FurnitureBrandedImageVisualization } from './FurnitureBrandedImageVisualization'; + +export class FurnitureBBVisualization extends FurnitureBrandedImageVisualization +{ + protected getLayerXOffset(scale: number, direction: number, layerId: number): number + { + return super.getLayerXOffset(scale, direction, layerId) + this._offsetX; + } + + protected getLayerYOffset(scale: number, direction: number, layerId: number): number + { + return super.getLayerYOffset(scale, direction, layerId) + this._offsetY; + } + + protected getLayerZOffset(scale: number, direction: number, layerId: number): number + { + return super.getLayerZOffset(scale, direction, layerId) + this._offsetZ; + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/furniture/FurnitureBadgeDisplayVisualization.ts b/src/nitro/room/object/visualization/furniture/FurnitureBadgeDisplayVisualization.ts new file mode 100644 index 00000000..e3c4183b --- /dev/null +++ b/src/nitro/room/object/visualization/furniture/FurnitureBadgeDisplayVisualization.ts @@ -0,0 +1,92 @@ +import { RoomObjectVariable } from '../../RoomObjectVariable'; +import { FurnitureAnimatedVisualization } from './FurnitureAnimatedVisualization'; + +export class FurnitureBadgeDisplayVisualization extends FurnitureAnimatedVisualization +{ + private static BADGE: string = 'BADGE'; + + private _badgeAssetNameNormalScale: string; + private _badgeAssetNameSmallScale: string; + private _badgeVisibleInState: number; + + constructor() + { + super(); + + this._badgeAssetNameNormalScale = ''; + this._badgeAssetNameSmallScale = ''; + this._badgeVisibleInState = -1; + } + + protected updateModel(scale: number): boolean + { + let updateModel = super.updateModel(scale); + + if(!isNaN(this.object.model.getValue(RoomObjectVariable.FURNITURE_BADGE_IMAGE_STATUS))) + { + const status = (this.object.model.getValue(RoomObjectVariable.FURNITURE_BADGE_IMAGE_STATUS) !== 0); + + if(status && this._badgeAssetNameNormalScale === '') + { + this._badgeAssetNameNormalScale = this.object.model.getValue(RoomObjectVariable.FURNITURE_BADGE_ASSET_NAME); + + if(this._badgeAssetNameSmallScale === '') this._badgeAssetNameSmallScale = this._badgeAssetNameNormalScale + '_32'; + + const visibleInState = this.object.model.getValue(RoomObjectVariable.FURNITURE_BADGE_VISIBLE_IN_STATE); + + if(!isNaN) this._badgeVisibleInState = visibleInState; + + updateModel = true; + } + } + + return updateModel; + } + + protected getSpriteAssetName(scale: number, layerId: number): string + { + const tag = this.getLayerTag(scale, this.direction, layerId); + + if((tag !== FurnitureBadgeDisplayVisualization.BADGE) || ((this._badgeVisibleInState !== -1) && (this.object.getState(0) !== this._badgeVisibleInState))) return super.getSpriteAssetName(scale, layerId); + + if(scale === 32) return this._badgeAssetNameSmallScale; + + return this._badgeAssetNameNormalScale; + } + + protected getLayerXOffset(scale: number, direction: number, layerId: number): number + { + let offset = super.getLayerXOffset(scale, direction, layerId); + + if(this.getLayerTag(scale, direction, layerId) === FurnitureBadgeDisplayVisualization.BADGE) + { + const asset = this.getAsset(((scale === 32) ? this._badgeAssetNameSmallScale : this._badgeAssetNameNormalScale), layerId); + + if(asset) + { + if(scale === 64) offset += ((40 - asset.width) / 2); + else offset += ((20 - asset.width) / 2); + } + } + + return offset; + } + + protected getLayerYOffset(scale: number, direction: number, layerId: number): number + { + let offset = super.getLayerYOffset(scale, direction, layerId); + + if(this.getLayerTag(scale, direction, layerId) === FurnitureBadgeDisplayVisualization.BADGE) + { + const asset = this.getAsset(((scale === 32) ? this._badgeAssetNameSmallScale : this._badgeAssetNameNormalScale), layerId); + + if(asset) + { + if(scale === 64) offset += ((40 - asset.height) / 2); + else offset += ((20 - asset.height) / 2); + } + } + + return offset; + } +} diff --git a/src/nitro/room/object/visualization/furniture/FurnitureBottleVisualization.ts b/src/nitro/room/object/visualization/furniture/FurnitureBottleVisualization.ts new file mode 100644 index 00000000..a223f9b6 --- /dev/null +++ b/src/nitro/room/object/visualization/furniture/FurnitureBottleVisualization.ts @@ -0,0 +1,62 @@ +import { FurnitureAnimatedVisualization } from './FurnitureAnimatedVisualization'; + +export class FurnitureBottleVisualization extends FurnitureAnimatedVisualization +{ + private static ANIMATION_ID_OFFSET_SLOW1: number = 20; + private static ANIMATION_ID_OFFSET_SLOW2: number = 9; + private static _Str_4186: number = -1; + + private _stateQueue: number[]; + private _running: boolean; + + constructor() + { + super(); + + this._stateQueue = []; + this._running = false; + } + + protected setAnimation(animationId: number): void + { + if(animationId === -1) + { + if(!this._running) + { + this._running = true; + this._stateQueue = []; + + this._stateQueue.push(FurnitureBottleVisualization._Str_4186); + + return; + } + } + + if((animationId >= 0) && (animationId <= 7)) + { + if(this._running) + { + this._running = false; + this._stateQueue = []; + + this._stateQueue.push(FurnitureBottleVisualization.ANIMATION_ID_OFFSET_SLOW1); + this._stateQueue.push(FurnitureBottleVisualization.ANIMATION_ID_OFFSET_SLOW2 + animationId); + this._stateQueue.push(animationId); + + return; + } + + super.setAnimation(animationId); + } + } + + protected updateAnimation(scale: number): number + { + if(this.getLastFramePlayed(0)) + { + if(this._stateQueue.length) super.setAnimation(this._stateQueue.shift()); + } + + return super.updateAnimation(scale); + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/furniture/FurnitureBrandedImageVisualization.ts b/src/nitro/room/object/visualization/furniture/FurnitureBrandedImageVisualization.ts new file mode 100644 index 00000000..db331687 --- /dev/null +++ b/src/nitro/room/object/visualization/furniture/FurnitureBrandedImageVisualization.ts @@ -0,0 +1,162 @@ +import { Texture } from 'pixi.js'; +import { Nitro } from '../../../../Nitro'; +import { RoomObjectVariable } from '../../RoomObjectVariable'; +import { FurnitureVisualization } from './FurnitureVisualization'; + +export class FurnitureBrandedImageVisualization extends FurnitureVisualization +{ + private static BRANDED_IMAGE: string = 'branded_image'; + + protected _imageUrl: string; + protected _shortUrl: string; + protected _imageReady: boolean; + + protected _offsetX: number; + protected _offsetY: number; + protected _offsetZ: number; + + constructor() + { + super(); + + this._imageUrl = null; + this._shortUrl = null; + this._imageReady = false; + + this._offsetX = 0; + this._offsetY = 0; + this._offsetZ = 0; + } + + public dispose(): void + { + super.dispose(); + + if(this._imageUrl) (this.asset && this.asset.disposeAsset(this._imageUrl)); + } + + protected updateObject(scale: number, direction: number): boolean + { + if(!super.updateObject(scale, direction)) return false; + + if(this._imageReady) this.checkAndCreateImageForCurrentState(); + + return true; + } + + protected updateModel(scale: number): boolean + { + const flag = super.updateModel(scale); + + if(flag) + { + this._offsetX = this.object.model.getValue(RoomObjectVariable.FURNITURE_BRANDING_OFFSET_X); + this._offsetY = this.object.model.getValue(RoomObjectVariable.FURNITURE_BRANDING_OFFSET_Y); + this._offsetZ = this.object.model.getValue(RoomObjectVariable.FURNITURE_BRANDING_OFFSET_Z); + } + + if(!this._imageReady) + { + this._imageReady = this.checkIfImageReady(); + + if(this._imageReady) + { + this.checkAndCreateImageForCurrentState(); + + return true; + } + } + else + { + if(this.checkIfImageChanged()) + { + this._imageReady = false; + this._imageUrl = null; + + return true; + } + } + + return flag; + } + + protected imageReady(texture: Texture, imageUrl: string): void + { + if(!texture) + { + this._imageUrl = null; + + return; + } + + this._imageUrl = imageUrl; + } + + private checkIfImageChanged(): boolean + { + const imageUrl = this.object.model.getValue(RoomObjectVariable.FURNITURE_BRANDING_IMAGE_URL); + + if(imageUrl && (imageUrl === this._imageUrl)) return false; + + (this.asset && this.asset.disposeAsset(this._imageUrl)); + + return true; + } + + protected checkIfImageReady(): boolean + { + const model = this.object && this.object.model; + + if(!model) return false; + + const imageUrl = this.object.model.getValue(RoomObjectVariable.FURNITURE_BRANDING_IMAGE_URL); + + if(!imageUrl) return false; + + if(this._imageUrl && (this._imageUrl === imageUrl)) return false; + + const imageStatus = this.object.model.getValue(RoomObjectVariable.FURNITURE_BRANDING_IMAGE_STATUS); + + if(imageStatus === 1) + { + const texture = Nitro.instance.core.asset.getTexture(imageUrl); + + if(!texture) return false; + + this.imageReady(texture, imageUrl); + + return true; + } + + return false; + } + + protected checkAndCreateImageForCurrentState(): void + { + if(!this._imageUrl) return; + + const texture = Nitro.instance.core.asset.getTexture(this._imageUrl); + + if(!texture) return; + + this.asset.addAsset(this._imageUrl, texture, true, 0, 0, false, false); + } + + protected getSpriteAssetName(scale: number, layerId: number): string + { + const tag = this.getLayerTag(scale, this._direction, layerId); + + if((tag === FurnitureBrandedImageVisualization.BRANDED_IMAGE) && this._imageUrl) return this._imageUrl; + + return super.getSpriteAssetName(scale, layerId); + } + + protected getLayerIgnoreMouse(scale: number, direction: number, layerId: number): boolean + { + const tag = this.getLayerTag(scale, direction, layerId); + + if(tag !== FurnitureBrandedImageVisualization.BRANDED_IMAGE) return super.getLayerIgnoreMouse(scale, direction, layerId); + + return true; + } +} diff --git a/src/nitro/room/object/visualization/furniture/FurnitureBuilderPlaceholderVisualization.ts b/src/nitro/room/object/visualization/furniture/FurnitureBuilderPlaceholderVisualization.ts new file mode 100644 index 00000000..ce769c05 --- /dev/null +++ b/src/nitro/room/object/visualization/furniture/FurnitureBuilderPlaceholderVisualization.ts @@ -0,0 +1,6 @@ +import { FurnitureVisualization } from './FurnitureVisualization'; + +export class FurnitureBuilderPlaceholderVisualization extends FurnitureVisualization +{ + +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/furniture/FurnitureCounterClockVisualization.ts b/src/nitro/room/object/visualization/furniture/FurnitureCounterClockVisualization.ts new file mode 100644 index 00000000..33757b42 --- /dev/null +++ b/src/nitro/room/object/visualization/furniture/FurnitureCounterClockVisualization.ts @@ -0,0 +1,29 @@ +import { FurnitureAnimatedVisualization } from './FurnitureAnimatedVisualization'; + +export class FurnitureCounterClockVisualization extends FurnitureAnimatedVisualization +{ + private static SECONDS_SPRITE: string = 'seconds_sprite'; + private static TEN_SECONDS_SPRITE: string = 'ten_seconds_sprite'; + private static MINUTES_SPRITE: string = 'minutes_sprite'; + private static TEN_MINUTES_SPRITE: string = 'ten_minutes_sprite'; + + protected getFrameNumber(scale: number, layerId: number): number + { + const tag = this.getLayerTag(scale, this.direction, layerId); + const animation = this.object.getState(0); + + switch(tag) + { + case FurnitureCounterClockVisualization.SECONDS_SPRITE: return Math.floor((animation % 60) % 10); + case FurnitureCounterClockVisualization.TEN_SECONDS_SPRITE: return Math.floor((animation % 60) / 10); + case FurnitureCounterClockVisualization.MINUTES_SPRITE: return Math.floor((animation / 60) % 10); + case FurnitureCounterClockVisualization.TEN_MINUTES_SPRITE: return Math.floor(((animation / 60) / 10) % 10); + default: return super.getFrameNumber(scale, layerId); + } + } + + public get animationId(): number + { + return 0; + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/furniture/FurnitureCuboidVisualization.ts b/src/nitro/room/object/visualization/furniture/FurnitureCuboidVisualization.ts new file mode 100644 index 00000000..2d1b54ff --- /dev/null +++ b/src/nitro/room/object/visualization/furniture/FurnitureCuboidVisualization.ts @@ -0,0 +1,6 @@ +import { RoomObjectSpriteVisualization } from '../../../../../room/object/visualization/RoomObjectSpriteVisualization'; + +export class FurnitureCuboidVisualization extends RoomObjectSpriteVisualization +{ + +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/furniture/FurnitureDynamicThumbnailVisualization.ts b/src/nitro/room/object/visualization/furniture/FurnitureDynamicThumbnailVisualization.ts new file mode 100644 index 00000000..a54b3195 --- /dev/null +++ b/src/nitro/room/object/visualization/furniture/FurnitureDynamicThumbnailVisualization.ts @@ -0,0 +1,55 @@ +import { SCALE_MODES, Texture } from 'pixi.js'; +import { FurnitureThumbnailVisualization } from './FurnitureThumbnailVisualization'; + +export class FurnitureDynamicThumbnailVisualization extends FurnitureThumbnailVisualization +{ + private _cachedUrl: string; + + constructor() + { + super(); + + this._cachedUrl = null; + } + + protected updateModel(scale: number): boolean + { + if(this.object) + { + const thumbnailUrl = this.getThumbnailURL(); + + if(this._cachedUrl !== thumbnailUrl) + { + this._cachedUrl = thumbnailUrl; + + if(this._cachedUrl && (this._cachedUrl !== '')) + { + const image = new Image(); + + image.src = thumbnailUrl; + image.crossOrigin = '*'; + + image.onload = () => + { + const texture = Texture.from(image); + + texture.baseTexture.scaleMode = SCALE_MODES.LINEAR; + + this._Str_6645(texture); + }; + } + else + { + this._Str_6645(null); + } + } + } + + return super.updateModel(scale); + } + + protected getThumbnailURL(): string + { + throw (new Error('This method must be overridden!')); + } +} diff --git a/src/nitro/room/object/visualization/furniture/FurnitureExternalImageVisualization.ts b/src/nitro/room/object/visualization/furniture/FurnitureExternalImageVisualization.ts new file mode 100644 index 00000000..4e6e3837 --- /dev/null +++ b/src/nitro/room/object/visualization/furniture/FurnitureExternalImageVisualization.ts @@ -0,0 +1,50 @@ +import { RoomObjectVariable } from '../../RoomObjectVariable'; +import { FurnitureDynamicThumbnailVisualization } from './FurnitureDynamicThumbnailVisualization'; + +export class FurnitureExternalImageVisualization extends FurnitureDynamicThumbnailVisualization +{ + private _url: string; + private _typePrefix: string; + + constructor() + { + super(); + + this._url = null; + this._typePrefix = null; + } + + protected getThumbnailURL(): string + { + if(!this.object) return null; + + if(this._url) return this._url; + + const jsonString = this.object.model.getValue(RoomObjectVariable.FURNITURE_DATA); + + if(!jsonString || jsonString === '') return null; + + if(this.object.type.indexOf('') >= 0) + + this._typePrefix = (this.object.type.indexOf('') >= 0) ? '' : 'postcards/selfie/'; + + const json = JSON.parse(jsonString); + + let url = (json.w || ''); + + url = this._Str_18056(url); + + this._url = url; + + return this._url; + } + + private _Str_18056(url: string): string + { + url = url.replace('.png', '_small.png'); + + if(url.indexOf('.png') === -1) url = (url + '_small.png'); + + return url; + } +} diff --git a/src/nitro/room/object/visualization/furniture/FurnitureFireworksVisualization.ts b/src/nitro/room/object/visualization/furniture/FurnitureFireworksVisualization.ts new file mode 100644 index 00000000..f23c2316 --- /dev/null +++ b/src/nitro/room/object/visualization/furniture/FurnitureFireworksVisualization.ts @@ -0,0 +1,6 @@ +import { FurnitureAnimatedVisualization } from './FurnitureAnimatedVisualization'; + +export class FurnitureFireworksVisualization extends FurnitureAnimatedVisualization +{ + +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/furniture/FurnitureGiftWrappedFireworksVisualization.ts b/src/nitro/room/object/visualization/furniture/FurnitureGiftWrappedFireworksVisualization.ts new file mode 100644 index 00000000..0832df4f --- /dev/null +++ b/src/nitro/room/object/visualization/furniture/FurnitureGiftWrappedFireworksVisualization.ts @@ -0,0 +1,79 @@ +import { IRoomGeometry } from '../../../../../room/utils/IRoomGeometry'; +import { RoomObjectVariable } from '../../RoomObjectVariable'; +import { FurnitureFireworksVisualization } from './FurnitureFireworksVisualization'; + +export class FurnitureGiftWrappedFireworksVisualization extends FurnitureFireworksVisualization +{ + private static PRESENT_DEFAULT_STATE: number = 0; + private static MAX_PACKET_TYPE_VALUE: number = 9; + private static MAX_RIBBON_TYPE_VALUE: number = 11; + + private _packetType:number = 0; + private _ribbonType:number = 0; + private _lastAnimationId: number = 0; + + public update(geometry: IRoomGeometry, time: number, update: boolean, skipUpdate: boolean) + { + this.updatePresentWrap(); + + super.update(geometry, time, update, skipUpdate); + } + + private updatePresentWrap(): void + { + if(!this.object) return; + + const local3 = 1000; + const extras = this.object.model.getValue(RoomObjectVariable.FURNITURE_EXTRAS); + + const typeIndex = parseInt(extras); + const packetType = Math.floor((typeIndex / local3)); + const ribbonType = (typeIndex % local3); + + this._packetType = ((packetType > FurnitureGiftWrappedFireworksVisualization.MAX_PACKET_TYPE_VALUE) ? 0 : packetType); + this._ribbonType = ((ribbonType > FurnitureGiftWrappedFireworksVisualization.MAX_RIBBON_TYPE_VALUE) ? 0 : ribbonType); + } + + public getFrameNumber(scale: number, layerId: number): number + { + if(this._lastAnimationId === FurnitureGiftWrappedFireworksVisualization.PRESENT_DEFAULT_STATE) + { + if(layerId <= 1) return this._packetType; + + if(layerId === 2) return this._ribbonType; + } + + return super.getFrameNumber(scale, layerId); + } + + public getSpriteAssetName(scale: number, layerId: number): string + { + const size = this.getValidSize(scale); + + let assetName = this._type; + let layerCode = ''; + + if(layerId < (this.spriteCount - 1)) + { + layerCode = String.fromCharCode(('a'.charCodeAt(0) + layerId)); + } + else + { + layerCode = 'sd'; + } + + const frameNumber = this.getFrameNumber(scale, layerId); + + assetName = (assetName + ((((('_' + size) + '_') + layerCode) + '_') + this.direction)); + assetName = (assetName + ('_' + frameNumber)); + + return assetName; + } + + protected setAnimation(animationId: number):void + { + this._lastAnimationId = animationId; + + super.setAnimation(animationId); + } +} diff --git a/src/nitro/room/object/visualization/furniture/FurnitureGiftWrappedVisualization.ts b/src/nitro/room/object/visualization/furniture/FurnitureGiftWrappedVisualization.ts new file mode 100644 index 00000000..467e1475 --- /dev/null +++ b/src/nitro/room/object/visualization/furniture/FurnitureGiftWrappedVisualization.ts @@ -0,0 +1,61 @@ +import { IRoomGeometry } from '../../../../../room/utils/IRoomGeometry'; +import { RoomObjectVariable } from '../../RoomObjectVariable'; +import { FurnitureVisualization } from './FurnitureVisualization'; + +export class FurnitureGiftWrappedVisualization extends FurnitureVisualization +{ + private _packetType: number = 0; + private _ribbonType: number = 0; + + public update(geometry: IRoomGeometry, time: number, update: boolean, skipUpdate: boolean): void + { + this.updatePresentWrap(); + + super.update(geometry, time, update, skipUpdate); + } + + private updatePresentWrap(): void + { + if(!this.object) return; + + const extras = this.object.model.getValue(RoomObjectVariable.FURNITURE_EXTRAS); + + const local3 = 1000; + const typeIndex = parseInt(extras); + + this._packetType = Math.floor((typeIndex / local3)); + this._ribbonType = (typeIndex % local3); + } + + public getFrameNumber(scale: number, layerId: number): number + { + if(layerId <= 1) return this._packetType; + + return this._ribbonType; + } + + public getSpriteAssetName(scale: number, layerId: number): string + { + const size = this.getValidSize(scale); + + let assetName = this._type; + let layerCode = ''; + + if(layerId < (this.spriteCount - 1)) + { + layerCode = String.fromCharCode(('a'.charCodeAt(0) + layerId)); + } + else + { + layerCode = 'sd'; + } + + const frameNumber = this.getFrameNumber(scale, layerId); + + assetName = (assetName + ((((('_' + size) + '_') + layerCode) + '_') + this.direction)); + assetName = (assetName + ('_' + frameNumber)); + + return assetName; + + } +} diff --git a/src/nitro/room/object/visualization/furniture/FurnitureGuildCustomizedVisualization.ts b/src/nitro/room/object/visualization/furniture/FurnitureGuildCustomizedVisualization.ts new file mode 100644 index 00000000..9a9a0b47 --- /dev/null +++ b/src/nitro/room/object/visualization/furniture/FurnitureGuildCustomizedVisualization.ts @@ -0,0 +1,44 @@ +import { RoomObjectVariable } from '../../RoomObjectVariable'; +import { FurnitureAnimatedVisualization } from './FurnitureAnimatedVisualization'; + +export class FurnitureGuildCustomizedVisualization extends FurnitureAnimatedVisualization +{ + public static DEFAULT_COLOR_1: number = 0xEEEEEE; + public static DEFAULT_COLOR_2: number = 0x4B4B4B; + + private _color1: number; + private _color2: number; + + constructor() + { + super(); + + this._color1 = FurnitureGuildCustomizedVisualization.DEFAULT_COLOR_1; + this._color2 = FurnitureGuildCustomizedVisualization.DEFAULT_COLOR_2; + } + + protected updateModel(scale: number): boolean + { + const flag = super.updateModel(scale); + + if(!flag) return false; + + this._color1 = this.object.model.getValue(RoomObjectVariable.FURNITURE_GUILD_CUSTOMIZED_COLOR_1); + this._color2 = this.object.model.getValue(RoomObjectVariable.FURNITURE_GUILD_CUSTOMIZED_COLOR_2); + + return flag; + } + + protected getLayerColor(scale: number, layerId: number, colorId: number): number + { + const tag = this.getLayerTag(scale, this._direction, layerId); + + switch(tag) + { + case 'COLOR1': return this._color1; + case 'COLOR2': return this._color2; + } + + return super.getLayerColor(scale, layerId, colorId); + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/furniture/FurnitureGuildIsometricBadgeVisualization.ts b/src/nitro/room/object/visualization/furniture/FurnitureGuildIsometricBadgeVisualization.ts new file mode 100644 index 00000000..31ac55e4 --- /dev/null +++ b/src/nitro/room/object/visualization/furniture/FurnitureGuildIsometricBadgeVisualization.ts @@ -0,0 +1,6 @@ +import { FurnitureThumbnailVisualization } from './FurnitureThumbnailVisualization'; + +export class FurnitureGuildIsometricBadgeVisualization extends FurnitureThumbnailVisualization +{ + +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/furniture/FurnitureHabboWheelVisualization.ts b/src/nitro/room/object/visualization/furniture/FurnitureHabboWheelVisualization.ts new file mode 100644 index 00000000..81bbe1bc --- /dev/null +++ b/src/nitro/room/object/visualization/furniture/FurnitureHabboWheelVisualization.ts @@ -0,0 +1,64 @@ +import { FurnitureAnimatedVisualization } from './FurnitureAnimatedVisualization'; + +export class FurnitureHabboWheelVisualization extends FurnitureAnimatedVisualization +{ + private static ANIMATION_ID_OFFSET_SLOW1: number = 10; + private static ANIMATION_ID_OFFSET_SLOW2: number = 20; + private static _Str_7627: number = 31; + private static _Str_4186: number = 32; + + private _stateQueue: number[]; + private _running: boolean; + + constructor() + { + super(); + + this._stateQueue = []; + this._running = false; + } + + protected setAnimation(animationId: number): void + { + if(animationId === -1) + { + if(!this._running) + { + this._running = true; + this._stateQueue = []; + + this._stateQueue.push(FurnitureHabboWheelVisualization._Str_7627); + this._stateQueue.push(FurnitureHabboWheelVisualization._Str_4186); + + return; + } + } + + if((animationId > 0) && (animationId <= FurnitureHabboWheelVisualization.ANIMATION_ID_OFFSET_SLOW1)) + { + if(this._running) + { + this._running = false; + this._stateQueue = []; + + this._stateQueue.push(FurnitureHabboWheelVisualization.ANIMATION_ID_OFFSET_SLOW1 + animationId); + this._stateQueue.push(FurnitureHabboWheelVisualization.ANIMATION_ID_OFFSET_SLOW2 + animationId); + this._stateQueue.push(animationId); + + return; + } + + super.setAnimation(animationId); + } + } + + protected updateAnimation(scale: number): number + { + if(this.getLastFramePlayed(1) && this.getLastFramePlayed(2) && this.getLastFramePlayed(3)) + { + if(this._stateQueue.length) super.setAnimation(this._stateQueue.shift()); + } + + return super.updateAnimation(scale); + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/furniture/FurnitureMannequinVisualization.ts b/src/nitro/room/object/visualization/furniture/FurnitureMannequinVisualization.ts new file mode 100644 index 00000000..0c9d88a8 --- /dev/null +++ b/src/nitro/room/object/visualization/furniture/FurnitureMannequinVisualization.ts @@ -0,0 +1,174 @@ +import { IObjectVisualizationData } from '../../../../../room/object/visualization/IRoomObjectVisualizationData'; +import { AvatarSetType } from '../../../../avatar/enum/AvatarSetType'; +import { IAvatarImageListener } from '../../../../avatar/IAvatarImageListener'; +import { RoomObjectVariable } from '../../RoomObjectVariable'; +import { FurnitureMannequinVisualizationData } from './FurnitureMannequinVisualizationData'; +import { FurnitureVisualization } from './FurnitureVisualization'; + +export class FurnitureMannequinVisualization extends FurnitureVisualization implements IAvatarImageListener +{ + private static AVATAR_IMAGE_SPRITE_TAG: string = 'avatar_image'; + + protected _data: FurnitureMannequinVisualizationData; + + private _mannequinScale: number; + private _figure: string; + private _gender: string; + private _dynamicAssetName: string; + private _needsUpdate: boolean; + + private _placeHolderFigure: string; + + private _disposed: boolean; + + constructor() + { + super(); + + this._mannequinScale = -1; + this._figure = null; + this._gender = null; + this._dynamicAssetName = null; + this._needsUpdate = false; + + this._placeHolderFigure = 'hd-99999-99998'; + + this._disposed = false; + } + + public initialize(data: IObjectVisualizationData): boolean + { + if(!(data instanceof FurnitureMannequinVisualizationData)) return false; + + return super.initialize(data); + } + + public dispose(): void + { + if(this._disposed) return; + + this._disposed = true; + + if(this._dynamicAssetName && this.asset) + { + this.asset.disposeAsset(this._dynamicAssetName); + + this._dynamicAssetName = null; + } + + super.dispose(); + } + + protected updateObject(scale: number, direction: number): boolean + { + const updateObject = super.updateObject(scale, direction); + + if(updateObject) + { + if(this._mannequinScale !== scale) + { + this._mannequinScale = scale; + + this.updateAvatar(); + } + } + + return updateObject; + } + + protected updateModel(scale: number): boolean + { + let updateModel = super.updateModel(scale); + + if(updateModel) + { + const figure = (this.object.model.getValue(RoomObjectVariable.FURNITURE_MANNEQUIN_FIGURE) || null); + + if(figure) + { + this._figure = (figure + '.' + this._placeHolderFigure); + this._gender = (this.object.model.getValue(RoomObjectVariable.FURNITURE_MANNEQUIN_GENDER) || null); + + this.updateAvatar(); + } + } + + updateModel = (updateModel || this._needsUpdate); + + this._needsUpdate = false; + + return updateModel; + } + + private updateAvatar(forceUpdate: boolean = false): void + { + if(!this.avatarExists() || forceUpdate) + { + const avatarImage = this._data.createAvatarImage(this._figure, this._mannequinScale, this._gender, this); + + if(avatarImage) + { + avatarImage.setDirection(AvatarSetType.FULL, this.direction); + + if(this._dynamicAssetName) this.asset.disposeAsset(this._dynamicAssetName); + + this.asset.addAsset(this._Str_10185(), avatarImage.getImage(AvatarSetType.FULL, false, 1, false), true); + + this._dynamicAssetName = this._Str_10185(); + this._needsUpdate = true; + + avatarImage.dispose(); + } + } + } + + private avatarExists(): boolean + { + return (this._figure && (this.getAsset(this._Str_10185()) !== null)); + } + + private _Str_10185(): string + { + return (((((('mannequin_' + this._figure) + '_') + this._mannequinScale) + '_') + this.direction) + '_') + this.object.id; + } + + public resetFigure(figure: string): void + { + if(figure === this._figure) this.updateAvatar(true); + } + + protected getSpriteAssetName(scale: number, layerId: number): string + { + const tag = this.getLayerTag(scale, this.direction, layerId); + + if(this._figure && (tag === FurnitureMannequinVisualization.AVATAR_IMAGE_SPRITE_TAG) && this.avatarExists()) + { + return this._Str_10185(); + } + + return super.getSpriteAssetName(scale, layerId); + } + + protected getLayerXOffset(scale: number, direction: number, layerId: number): number + { + const tag = this.getLayerTag(scale, direction, layerId); + + if((tag === FurnitureMannequinVisualization.AVATAR_IMAGE_SPRITE_TAG) && this.avatarExists()) return (-(this.getSprite(layerId).width) / 2); + + return super.getLayerXOffset(scale, direction, layerId); + } + + protected getLayerYOffset(scale: number, direction: number, layerId: number): number + { + const tag = this.getLayerTag(scale, direction, layerId); + + if((tag === FurnitureMannequinVisualization.AVATAR_IMAGE_SPRITE_TAG) && this.avatarExists()) return -(this.getSprite(layerId).height); + + return super.getLayerYOffset(scale, direction, layerId); + } + + public get disposed(): boolean + { + return this._disposed; + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/furniture/FurnitureMannequinVisualizationData.ts b/src/nitro/room/object/visualization/furniture/FurnitureMannequinVisualizationData.ts new file mode 100644 index 00000000..499e7987 --- /dev/null +++ b/src/nitro/room/object/visualization/furniture/FurnitureMannequinVisualizationData.ts @@ -0,0 +1,40 @@ +import { IAvatarEffectListener } from '../../../../avatar/IAvatarEffectListener'; +import { IAvatarImage } from '../../../../avatar/IAvatarImage'; +import { IAvatarImageListener } from '../../../../avatar/IAvatarImageListener'; +import { IAvatarRenderManager } from '../../../../avatar/IAvatarRenderManager'; +import { AvatarVisualizationData } from '../avatar/AvatarVisualizationData'; +import { FurnitureVisualizationData } from './FurnitureVisualizationData'; + +export class FurnitureMannequinVisualizationData extends FurnitureVisualizationData +{ + private _avatarData: AvatarVisualizationData; + + constructor() + { + super(); + + this._avatarData = new AvatarVisualizationData(); + } + + public dispose(): void + { + super.dispose(); + + if(this._avatarData) + { + this._avatarData.dispose(); + + this._avatarData = null; + } + } + + public createAvatarImage(figure: string, size: number, gender: string = null, avatarListener: IAvatarImageListener = null, effectListener: IAvatarEffectListener = null): IAvatarImage + { + return this._avatarData.createAvatarImage(figure,size, gender, avatarListener, effectListener); + } + + public set avatarManager(renderer: IAvatarRenderManager) + { + this._avatarData.avatarManager = renderer; + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/furniture/FurnitureParticleSystemEmitter.ts b/src/nitro/room/object/visualization/furniture/FurnitureParticleSystemEmitter.ts new file mode 100644 index 00000000..01b9505f --- /dev/null +++ b/src/nitro/room/object/visualization/furniture/FurnitureParticleSystemEmitter.ts @@ -0,0 +1,276 @@ +import { GraphicAsset } from '../../../../../room/object/visualization/utils/GraphicAsset'; +import { Vector3D } from '../../../../avatar/geometry/Vector3D'; +import { FurnitureParticleSystemParticle } from './FurnitureParticleSystemParticle'; + +export class FurnitureParticleSystemEmitter extends FurnitureParticleSystemParticle +{ + public static CONE: string = 'cone'; + public static PLANE: string = 'plane'; + public static SPHERE: string = 'sphere'; + + private _name: string; + private _roomObjectSpriteId: number = -1; + private _force: number; + private _timeStep: number = 0.1; + private _gravity: number; + private _airFriction: number; + private _explosionShape: string; + private _particleConfigurations: { [index: string]: any }[]; + private _particles: FurnitureParticleSystemParticle[]; + private _maxNumberOfParticles: number; + private _particlesPerFrame: number; + private _emittedParticles: number; + private _fuseTime: number = 10; + private _energy: number = 1; + private _hasIgnited: boolean = false; + private _burstPulse: number = 1; + + constructor(k: string='', _arg_2: number=-1) + { + super(); + + this._particles = []; + this._name = k; + this._roomObjectSpriteId = _arg_2; + this._particleConfigurations = []; + } + + public dispose(): void + { + for(const k of this._particles) k.dispose(); + + this._particles = null; + this._direction = null; + this._particleConfigurations = null; + + super.dispose(); + } + + public setup(k: number, _arg_2: number, _arg_3: number, _arg_4: Vector3D, _arg_5: number, _arg_6: number, _arg_7: string, _arg_8: number, _arg_9: number, _arg_10: number): void + { + this._maxNumberOfParticles = k; + this._particlesPerFrame = _arg_2; + this._force = _arg_3; + this._direction = _arg_4; + this._direction.normalize(); + this._gravity = _arg_5; + this._airFriction = _arg_6; + this._explosionShape = _arg_7; + this._fuseTime = _arg_9; + this._energy = _arg_8; + this._burstPulse = _arg_10; + this.reset(); + } + + public reset(): void + { + let k:FurnitureParticleSystemParticle; + for(const k of this._particles) k.dispose(); + this._particles = []; + this._emittedParticles = 0; + this._hasIgnited = false; + this.init(0, 0, 0, this._direction, this._force, this._timeStep, this._fuseTime, true); + } + + public _Str_17988(k:FurnitureParticleSystemEmitter, _arg_2: number): void + { + super.copy(k, _arg_2); + this._force = k._force; + this._direction = k._direction; + this._gravity = k._gravity; + this._airFriction = k._airFriction; + this._explosionShape = k._explosionShape; + this._fuseTime = k._fuseTime; + this._energy = k._energy; + this._burstPulse = k._burstPulse; + this._timeStep = k._timeStep; + this._hasIgnited = k._hasIgnited; + } + + public _Str_24892(k: number, _arg_2: boolean, _arg_3: GraphicAsset[], _arg_4: boolean): void + { + const _local_5 = []; + _local_5['lifeTime'] = k; + _local_5['isEmitter'] = _arg_2; + _local_5['frames'] = _arg_3; + _local_5['fade'] = _arg_4; + this._particleConfigurations.push(_local_5); + } + + protected ignite(): void + { + this._hasIgnited = true; + if((this._emittedParticles < this._maxNumberOfParticles)) + { + if(this.age > 1) + { + this._Str_19068(this, this.direction); + } + } + } + + private _Str_19068(k:FurnitureParticleSystemParticle, _arg_2: Vector3D = null): void + { + if(!_arg_2) _arg_2 = new Vector3D(); + + const _local_3 = new Vector3D(); + const _local_5 = this._Str_23904(); + + let _local_10 = 0; + + while(_local_10 < this._particlesPerFrame) + { + switch(this._explosionShape) + { + case FurnitureParticleSystemEmitter.CONE: + _local_3.x = ((this._Str_7471(0.5)) ? Math.random() : -(Math.random())); + _local_3.y = -(Math.random() + 1); + _local_3.z = ((this._Str_7471(0.5)) ? Math.random() : -(Math.random())); + break; + case FurnitureParticleSystemEmitter.PLANE: + _local_3.x = ((this._Str_7471(0.5)) ? Math.random() : -(Math.random())); + _local_3.y = 0; + _local_3.z = ((this._Str_7471(0.5)) ? Math.random() : -(Math.random())); + break; + case FurnitureParticleSystemEmitter.SPHERE: + _local_3.x = ((this._Str_7471(0.5)) ? Math.random() : -(Math.random())); + _local_3.y = ((this._Str_7471(0.5)) ? Math.random() : -(Math.random())); + _local_3.z = ((this._Str_7471(0.5)) ? Math.random() : -(Math.random())); + break; + } + + _local_3.normalize(); + + const _local_4 = new FurnitureParticleSystemParticle(); + + let _local_6 = 0; + let _local_7 = false; + let _local_8 = false; + let _local_9: GraphicAsset[] = []; + + if(_local_5) + { + _local_6 = Math.floor(((Math.random() * _local_5['lifeTime']) + 10)); + _local_7 = _local_5['isEmitter']; + _local_9 = _local_5['frames']; + _local_8 = _local_5['fade']; + } + else + { + _local_6 = Math.trunc(Math.floor(((Math.random() * 20) + 10))); + _local_7 = false; + _local_9 = []; + } + + _local_4.init(k.x, k.y, k.z, _local_3, this._energy, this._timeStep, _local_6, _local_7, _local_9, _local_8); + + this._particles.push(_local_4); + this._emittedParticles++; + + _local_10++; + } + } + + private _Str_23904() + { + const k: number = Math.trunc(Math.floor((Math.random() * this._particleConfigurations.length))); + return this._particleConfigurations[k]; + } + + public update(): void + { + super.update(); + this._Str_25039(); + this._Str_25400(); + this._Str_23140(); + if(((!(this._Str_16034)) && (this._emittedParticles < this._maxNumberOfParticles))) + { + if((this.age % this._burstPulse) == 0) + { + this._Str_19068(this, this.direction); + } + } + } + + public _Str_25400(): void + { + let _local_2:FurnitureParticleSystemParticle; + let _local_3: number; + let _local_4: number; + let _local_5: number; + if(((this._Str_16034) || (this._emittedParticles < this._maxNumberOfParticles))) + { + _local_3 = this.x; + _local_4 = this.y; + _local_5 = this.z; + this.x = (((2 - this._airFriction) * this.x) - ((1 - this._airFriction) * this._Str_10744)); + this.y = ((((2 - this._airFriction) * this.y) - ((1 - this._airFriction) * this._Str_12459)) + ((this._gravity * this._timeStep) * this._timeStep)); + this.z = (((2 - this._airFriction) * this.z) - ((1 - this._airFriction) * this._Str_11680)); + this._Str_10744 = _local_3; + this._Str_12459 = _local_4; + this._Str_11680 = _local_5; + } + const k: FurnitureParticleSystemParticle[] = []; + + for(const _local_2 of this._particles) + { + _local_2.update(); + _local_3 = _local_2.x; + _local_4 = _local_2.y; + _local_5 = _local_2.z; + _local_2.x = (((2 - this._airFriction) * _local_2.x) - ((1 - this._airFriction) * _local_2._Str_10744)); + _local_2.y = ((((2 - this._airFriction) * _local_2.y) - ((1 - this._airFriction) * _local_2._Str_12459)) + ((this._gravity * this._timeStep) * this._timeStep)); + _local_2.z = (((2 - this._airFriction) * _local_2.z) - ((1 - this._airFriction) * _local_2._Str_11680)); + _local_2._Str_10744 = _local_3; + _local_2._Str_12459 = _local_4; + _local_2._Str_11680 = _local_5; + if(((_local_2.y > 10) || (!(_local_2._Str_16034)))) + { + k.push(_local_2); + } + } + for(const _local_2 of k) + { + if(_local_2.isEmitter) + { + // + } + + this._particles.splice(this._particles.indexOf(_local_2), 1); + + _local_2.dispose(); + } + } + + private _Str_23140(): void + { + } + + private _Str_25039(): void + { + for(const k of this._particles) + { + // + } + } + + public get particles(): FurnitureParticleSystemParticle[] + { + return this._particles; + } + + public get _Str_22727(): boolean + { + return this._hasIgnited; + } + + private _Str_7471(k: number): boolean + { + return Math.random() < k; + } + + public get _Str_9107(): number + { + return this._roomObjectSpriteId; + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/furniture/FurnitureParticleSystemParticle.ts b/src/nitro/room/object/visualization/furniture/FurnitureParticleSystemParticle.ts new file mode 100644 index 00000000..ec675c20 --- /dev/null +++ b/src/nitro/room/object/visualization/furniture/FurnitureParticleSystemParticle.ts @@ -0,0 +1,200 @@ +import { GraphicAsset } from '../../../../../room/object/visualization/utils/GraphicAsset'; +import { Vector3D } from '../../../../avatar/geometry/Vector3D'; + +export class FurnitureParticleSystemParticle +{ + private _x: number; + private _y: number; + private _z: number; + private _lastX: number; + private _lastY: number; + private _lastZ: number; + private _hasMoved: boolean = false; + protected _direction: Vector3D; + private _age: number = 0; + private _lifeTime: number; + private _isEmitter: boolean = false; + private _fade: boolean = false; + private _fadeTime: number; + private _alphaMultiplier: number = 1; + private _frames: GraphicAsset[]; + + public init(k: number, _arg_2: number, _arg_3: number, _arg_4: Vector3D, _arg_5: number, _arg_6: number, _arg_7: number, _arg_8: boolean = false, _arg_9: GraphicAsset[] = null, _arg_10: boolean = false): void + { + this._x = k; + this._y = _arg_2; + this._z = _arg_3; + this._direction = new Vector3D(_arg_4.x, _arg_4.y, _arg_4.z); + + this._direction.x *= _arg_5; + this._direction.y *= _arg_5; + this._direction.z *= _arg_5; + + this._lastX = (this._x - (this._direction.x * _arg_6)); + this._lastY = (this._y - (this._direction.y * _arg_6)); + this._lastZ = (this._z - (this._direction.z * _arg_6)); + this._age = 0; + this._hasMoved = false; + this._lifeTime = _arg_7; + this._isEmitter = _arg_8; + this._frames = _arg_9; + this._fade = _arg_10; + this._alphaMultiplier = 1; + this._fadeTime = (0.5 + (Math.random() * 0.5)); + } + + public dispose(): void + { + this._direction = null; + } + + public update(): void + { + this._age++; + if(this._age == this._lifeTime) + { + this.ignite(); + } + if(this._fade) + { + if((this._age / this._lifeTime) > this._fadeTime) + { + this._alphaMultiplier = ((this._lifeTime - this._age) / (this._lifeTime * (1 - this._fadeTime))); + } + } + } + + public getAsset(): GraphicAsset + { + if(((this._frames) && (this._frames.length > 0))) + { + return this._frames[(this._age % this._frames.length)]; + } + return null; + } + + protected ignite(): void + { + } + + public get fade(): boolean + { + return this._fade; + } + + public get alphaMultiplier(): number + { + return this._alphaMultiplier; + } + + public get direction(): Vector3D + { + return this._direction; + } + + public get age(): number + { + return this._age; + } + + public get isEmitter(): boolean + { + return this._isEmitter; + } + + public get _Str_16034(): boolean + { + return this._age <= this._lifeTime; + } + + public get x(): number + { + return this._x; + } + + public set x(k: number) + { + this._x = k; + } + + public get y(): number + { + return this._y; + } + + public set y(k: number) + { + this._y = k; + } + + public get z(): number + { + return this._z; + } + + public set z(k: number) + { + this._z = k; + } + + public get _Str_10744(): number + { + return this._lastX; + } + + public set _Str_10744(k: number) + { + this._hasMoved = true; + this._lastX = k; + } + + public get _Str_12459(): number + { + return this._lastY; + } + + public set _Str_12459(k: number) + { + this._hasMoved = true; + this._lastY = k; + } + + public get _Str_11680(): number + { + return this._lastZ; + } + + public set _Str_11680(k: number) + { + this._hasMoved = true; + this._lastZ = k; + } + + public get _Str_22611(): boolean + { + return this._hasMoved; + } + + public toString(): string + { + return [ this._x, this._y, this._z ].toString(); + } + + public copy(k:FurnitureParticleSystemParticle, _arg_2: number): void + { + this._x = (k._x * _arg_2); + this._y = (k._y * _arg_2); + this._z = (k._z * _arg_2); + this._lastX = (k._lastX * _arg_2); + this._lastY = (k._lastY * _arg_2); + this._lastZ = (k._lastZ * _arg_2); + this._hasMoved = k._Str_22611; + this._direction = k._direction; + this._age = k._age; + this._lifeTime = k._lifeTime; + this._isEmitter = k._isEmitter; + this._fade = k._fade; + this._fadeTime = k._fadeTime; + this._alphaMultiplier = k._alphaMultiplier; + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/furniture/FurniturePartyBeamerVisualization.ts b/src/nitro/room/object/visualization/furniture/FurniturePartyBeamerVisualization.ts new file mode 100644 index 00000000..8e4799c6 --- /dev/null +++ b/src/nitro/room/object/visualization/furniture/FurniturePartyBeamerVisualization.ts @@ -0,0 +1,6 @@ +import { FurnitureAnimatedVisualization } from './FurnitureAnimatedVisualization'; + +export class FurniturePartyBeamerVisualization extends FurnitureAnimatedVisualization +{ + +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/furniture/FurniturePlanetSystemVisualization.ts b/src/nitro/room/object/visualization/furniture/FurniturePlanetSystemVisualization.ts new file mode 100644 index 00000000..bcf8c7e0 --- /dev/null +++ b/src/nitro/room/object/visualization/furniture/FurniturePlanetSystemVisualization.ts @@ -0,0 +1,6 @@ +import { FurnitureAnimatedVisualization } from './FurnitureAnimatedVisualization'; + +export class FurniturePlanetSystemVisualization extends FurnitureAnimatedVisualization +{ + +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/furniture/FurniturePosterVisualization.ts b/src/nitro/room/object/visualization/furniture/FurniturePosterVisualization.ts new file mode 100644 index 00000000..eea41eb5 --- /dev/null +++ b/src/nitro/room/object/visualization/furniture/FurniturePosterVisualization.ts @@ -0,0 +1,6 @@ +import { FurnitureVisualization } from './FurnitureVisualization'; + +export class FurniturePosterVisualization extends FurnitureVisualization +{ + +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/furniture/FurnitureQueueTileVisualization.ts b/src/nitro/room/object/visualization/furniture/FurnitureQueueTileVisualization.ts new file mode 100644 index 00000000..ea30a559 --- /dev/null +++ b/src/nitro/room/object/visualization/furniture/FurnitureQueueTileVisualization.ts @@ -0,0 +1,50 @@ +import { FurnitureAnimatedVisualization } from './FurnitureAnimatedVisualization'; + +export class FurnitureQueueTileVisualization extends FurnitureAnimatedVisualization +{ + private static _Str_4186: number = 3; + private static _Str_18395: number = 2; + private static _Str_15915: number = 1; + private static _Str_16054: number = 15; + + private _stateQueue: number[]; + private _animationCounter: number; + + constructor() + { + super(); + + this._stateQueue = []; + this._animationCounter = -1; + } + + protected setAnimation(animationId: number): void + { + if(animationId === FurnitureQueueTileVisualization._Str_18395) + { + this._stateQueue = []; + this._stateQueue.push(FurnitureQueueTileVisualization._Str_15915); + + this._animationCounter = FurnitureQueueTileVisualization._Str_16054; + } + + return super.setAnimation(animationId); + } + + protected updateAnimation(scale: number): number + { + if(this._animationCounter > 0) this._animationCounter--; + + if(!this._animationCounter) + { + if(this._stateQueue.length) super.setAnimation(this._stateQueue.shift()); + } + + return super.updateAnimation(scale); + } + + protected usesAnimationResetting(): boolean + { + return true; + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/furniture/FurnitureResettingAnimatedVisualization.ts b/src/nitro/room/object/visualization/furniture/FurnitureResettingAnimatedVisualization.ts new file mode 100644 index 00000000..dd191e9a --- /dev/null +++ b/src/nitro/room/object/visualization/furniture/FurnitureResettingAnimatedVisualization.ts @@ -0,0 +1,9 @@ +import { FurnitureAnimatedVisualization } from './FurnitureAnimatedVisualization'; + +export class FurnitureResettingAnimatedVisualization extends FurnitureAnimatedVisualization +{ + protected usesAnimationResetting(): boolean + { + return true; + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/furniture/FurnitureRoomBackgroundVisualization.ts b/src/nitro/room/object/visualization/furniture/FurnitureRoomBackgroundVisualization.ts new file mode 100644 index 00000000..60d52c8c --- /dev/null +++ b/src/nitro/room/object/visualization/furniture/FurnitureRoomBackgroundVisualization.ts @@ -0,0 +1,59 @@ +import { Texture } from 'pixi.js'; +import { DirectionalOffsetData } from '../data/DirectionalOffsetData'; +import { FurnitureBrandedImageVisualization } from './FurnitureBrandedImageVisualization'; + +export class FurnitureRoomBackgroundVisualization extends FurnitureBrandedImageVisualization +{ + private _imageOffset: DirectionalOffsetData; + + protected imageReady(texture: Texture, imageUrl: string): void + { + super.imageReady(texture, imageUrl); + + if(!texture) return; + + this.setImageOffset(texture.width, texture.height); + } + + private setImageOffset(width: number, height: number): void + { + const offsetData = new DirectionalOffsetData(); + + offsetData.setDirection(1, 0, -height); + offsetData.setDirection(3, 0, 0); + offsetData.setDirection(5, -width, 0); + offsetData.setDirection(7, -width, -height); + offsetData.setDirection(4, (-width / 2), (-height / 2)); + + this._imageOffset = offsetData; + } + + protected getLayerXOffset(scale: number, direction: number, layerId: number): number + { + if(this._imageOffset) + { + const offset = this._imageOffset.getXOffset(direction, 0); + + if(offset !== undefined) return offset + this._offsetX; + } + + return super.getLayerXOffset(scale, direction, layerId) + this._offsetX; + } + + protected getLayerYOffset(scale: number, direction: number, layerId: number): number + { + if(this._imageOffset) + { + const offset = this._imageOffset.getYOffset(direction, 0); + + if(offset !== undefined) return offset + this._offsetY; + } + + return super.getLayerYOffset(scale, direction, layerId) + this._offsetY; + } + + protected getLayerZOffset(scale: number, direction: number, layerId: number): number + { + return super.getLayerZOffset(scale, direction, layerId) + (-(this._offsetZ)); + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/furniture/FurnitureScoreBoardVisualization.ts b/src/nitro/room/object/visualization/furniture/FurnitureScoreBoardVisualization.ts new file mode 100644 index 00000000..05371c6d --- /dev/null +++ b/src/nitro/room/object/visualization/furniture/FurnitureScoreBoardVisualization.ts @@ -0,0 +1,24 @@ +import { FurnitureAnimatedVisualization } from './FurnitureAnimatedVisualization'; + +export class FurnitureScoreBoardVisualization extends FurnitureAnimatedVisualization +{ + private static ONES_SPRITE: string = 'ones_sprite'; + private static TENS_SPRITE: string = 'tens_sprite'; + private static HUNDREDS_SPRITE: string = 'hundreds_sprite'; + private static THOUSANDS_SPRITE: string = 'thousands_sprite'; + + protected getFrameNumber(scale: number, layerId: number): number + { + const tag = this.getLayerTag(scale, this.direction, layerId); + const animation = this.object.getState(0); + + switch(tag) + { + case FurnitureScoreBoardVisualization.ONES_SPRITE: return Math.floor(animation % 10); + case FurnitureScoreBoardVisualization.TENS_SPRITE: return Math.floor((animation / 10) % 10); + case FurnitureScoreBoardVisualization.HUNDREDS_SPRITE: return Math.floor((animation / 100) % 10); + case FurnitureScoreBoardVisualization.THOUSANDS_SPRITE: return Math.floor((animation / 1000) % 10); + default: return super.getFrameNumber(scale, layerId); + } + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/furniture/FurnitureSoundBlockVisualization.ts b/src/nitro/room/object/visualization/furniture/FurnitureSoundBlockVisualization.ts new file mode 100644 index 00000000..ca6e557e --- /dev/null +++ b/src/nitro/room/object/visualization/furniture/FurnitureSoundBlockVisualization.ts @@ -0,0 +1,6 @@ +import { FurnitureAnimatedVisualization } from './FurnitureAnimatedVisualization'; + +export class FurnitureSoundBlockVisualization extends FurnitureAnimatedVisualization +{ + +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/furniture/FurnitureStickieVisualization.ts b/src/nitro/room/object/visualization/furniture/FurnitureStickieVisualization.ts new file mode 100644 index 00000000..76fb3b68 --- /dev/null +++ b/src/nitro/room/object/visualization/furniture/FurnitureStickieVisualization.ts @@ -0,0 +1,12 @@ +import { ColorData } from '../data/ColorData'; +import { FurnitureVisualization } from './FurnitureVisualization'; + +export class FurnitureStickieVisualization extends FurnitureVisualization +{ + protected getLayerColor(scale: number, layerId: number, colorId: number): number + { + if(!this._data) return ColorData.DEFAULT_COLOR; + + return this._data.getLayerColor(scale, layerId, colorId); + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/furniture/FurnitureThumbnailVisualization.ts b/src/nitro/room/object/visualization/furniture/FurnitureThumbnailVisualization.ts new file mode 100644 index 00000000..407113f2 --- /dev/null +++ b/src/nitro/room/object/visualization/furniture/FurnitureThumbnailVisualization.ts @@ -0,0 +1,150 @@ +import { Matrix, Rectangle, Sprite, Texture } from 'pixi.js'; +import { IGraphicAsset } from '../../../../../room/object/visualization/utils/IGraphicAsset'; +import { TextureUtils } from '../../../../../room/utils/TextureUtils'; +import { FurnitureAnimatedVisualization } from './FurnitureAnimatedVisualization'; + +export class FurnitureThumbnailVisualization extends FurnitureAnimatedVisualization +{ + protected static THUMBNAIL: string = 'THUMBNAIL'; + + private _Str_22237: string; + private _Str_10040: Texture; + private _Str_21698: number; + private _Str_16232: boolean; + + constructor() + { + super(); + + this._Str_22237 = null; + this._Str_10040 = null; + this._Str_21698 = -1; + this._Str_16232 = false; + } + + public get _Str_23660(): boolean + { + return !(this._Str_10040 == null); + } + + public _Str_6645(k: Texture): void + { + this._Str_10040 = k; + this._Str_16232 = true; + } + + protected updateModel(scale: number): boolean + { + const flag = super.updateModel(scale); + + if(!this._Str_16232 && (this._Str_21698 === this.direction)) return flag; + + this._Str_25236(); + + return true; + } + + private _Str_25236(): void + { + if(this.asset == null) return; + + if(this._Str_10040) + { + this._Str_20857(this._Str_10040, 64); + } + else + { + this.asset.disposeAsset(this._Str_15493(64)); + } + + this._Str_16232 = false; + this._Str_21698 = this.direction; + } + + private _Str_20857(k: Texture, scale: number): void + { + let layerId = 0; + + while(layerId < this.totalSprites) + { + if(this.getLayerTag(scale, this.direction, layerId) === FurnitureThumbnailVisualization.THUMBNAIL) + { + const assetName = (this.cacheSpriteAssetName(scale, layerId, false) + this.getFrameNumber(scale, layerId)); + const asset = this.getAsset(assetName, layerId); + + if(asset) + { + const _local_6 = this._Str_25562(k, asset); + const _local_7 = this._Str_15493(scale); + + this.asset.disposeAsset(_local_7); + this.asset.addAsset(_local_7, _local_6, true, asset.offsetX, asset.offsetY, false, false); + } + + return; + } + + layerId++; + } + } + + private _Str_25562(texture: Texture, asset: IGraphicAsset): Texture + { + const _local_3 = 1.1; + const matrix = new Matrix(); + const _local_5 = (asset.width / texture.width); + + switch(this.direction) + { + case 2: + matrix.a = _local_5; + matrix.b = (-0.5 * _local_5); + matrix.c = 0; + matrix.d = (_local_5 * _local_3); + matrix.tx = 0; + matrix.ty = ((0.5 * _local_5) * texture.width); + break; + case 0: + case 4: + matrix.a = _local_5; + matrix.b = (0.5 * _local_5); + matrix.c = 0; + matrix.d = (_local_5 * _local_3); + matrix.tx = 0; + matrix.ty = 0; + break; + default: + matrix.a = _local_5; + matrix.b = 0; + matrix.c = 0; + matrix.d = _local_5; + matrix.tx = 0; + matrix.ty = 0; + } + + const sprite = Sprite.from(texture); + + sprite.transform.setFromMatrix(matrix); + + return TextureUtils.generateTexture(sprite, new Rectangle(0, 0, asset.width, asset.height)); + } + + protected getSpriteAssetName(scale: number, layerId: number): string + { + if(this._Str_10040 && (this.getLayerTag(scale, this.direction, layerId) === FurnitureThumbnailVisualization.THUMBNAIL)) return this._Str_15493(scale); + + return super.getSpriteAssetName(scale, layerId); + } + + protected _Str_15493(scale: number): string + { + this._Str_22237 = this._Str_12961(this.object.id, 64); + + return this._Str_22237; + } + + protected _Str_12961(k: number, _arg_2: number): string + { + return [this._type, k, 'thumb', _arg_2].join('_'); + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/furniture/FurnitureValRandomizerVisualization.ts b/src/nitro/room/object/visualization/furniture/FurnitureValRandomizerVisualization.ts new file mode 100644 index 00000000..610620b0 --- /dev/null +++ b/src/nitro/room/object/visualization/furniture/FurnitureValRandomizerVisualization.ts @@ -0,0 +1,76 @@ +import { FurnitureAnimatedVisualization } from './FurnitureAnimatedVisualization'; + +export class FurnitureValRandomizerVisualization extends FurnitureAnimatedVisualization +{ + private static ANIMATION_ID_OFFSET_SLOW1: number = 20; + private static ANIMATION_ID_OFFSET_SLOW2: number = 10; + private static _Str_7627: number = 31; + private static _Str_4186: number = 32; + private static _Str_11236: number = 30; + + private _stateQueue: number[]; + private _running: boolean; + + constructor() + { + super(); + + this._stateQueue = []; + this._running = false; + + super.setAnimation(FurnitureValRandomizerVisualization._Str_11236); + } + + protected setAnimation(animationId: number): void + { + if(animationId === 0) + { + if(!this._running) + { + this._running = true; + this._stateQueue = []; + + this._stateQueue.push(FurnitureValRandomizerVisualization._Str_7627); + this._stateQueue.push(FurnitureValRandomizerVisualization._Str_4186); + + return; + } + } + + if((animationId > 0) && (animationId <= FurnitureValRandomizerVisualization.ANIMATION_ID_OFFSET_SLOW2)) + { + if(this._running) + { + this._running = false; + this._stateQueue = []; + + if(this.direction === 2) + { + this._stateQueue.push(FurnitureValRandomizerVisualization.ANIMATION_ID_OFFSET_SLOW1 + 5); + this._stateQueue.push(FurnitureValRandomizerVisualization.ANIMATION_ID_OFFSET_SLOW2 + 5); + } + else + { + this._stateQueue.push(FurnitureValRandomizerVisualization.ANIMATION_ID_OFFSET_SLOW1 + animationId); + this._stateQueue.push(FurnitureValRandomizerVisualization.ANIMATION_ID_OFFSET_SLOW2 + animationId); + } + + this._stateQueue.push(FurnitureValRandomizerVisualization._Str_11236); + + return; + } + + super.setAnimation(FurnitureValRandomizerVisualization._Str_11236); + } + } + + protected updateAnimation(scale: number): number + { + if(this.getLastFramePlayed(11)) + { + if(this._stateQueue.length) super.setAnimation(this._stateQueue.shift()); + } + + return super.updateAnimation(scale); + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/furniture/FurnitureVisualization.ts b/src/nitro/room/object/visualization/furniture/FurnitureVisualization.ts new file mode 100644 index 00000000..22463980 --- /dev/null +++ b/src/nitro/room/object/visualization/furniture/FurnitureVisualization.ts @@ -0,0 +1,583 @@ +import { AlphaTolerance } from '../../../../../room/object/enum/AlphaTolerance'; +import { IRoomObjectSprite } from '../../../../../room/object/visualization/IRoomObjectSprite'; +import { IObjectVisualizationData } from '../../../../../room/object/visualization/IRoomObjectVisualizationData'; +import { RoomObjectSpriteVisualization } from '../../../../../room/object/visualization/RoomObjectSpriteVisualization'; +import { IGraphicAsset } from '../../../../../room/object/visualization/utils/IGraphicAsset'; +import { IRoomGeometry } from '../../../../../room/utils/IRoomGeometry'; +import { RoomObjectVariable } from '../../RoomObjectVariable'; +import { RoomObjectVisualizationType } from '../../RoomObjectVisualizationType'; +import { ColorData } from '../data/ColorData'; +import { LayerData } from '../data/LayerData'; +import { FurnitureVisualizationData } from './FurnitureVisualizationData'; + +export class FurnitureVisualization extends RoomObjectSpriteVisualization +{ + protected static DEPTH_MULTIPLIER: number = Math.sqrt(0.5); + + public static TYPE: string = RoomObjectVisualizationType.FURNITURE_STATIC; + + protected _data: FurnitureVisualizationData; + + protected _type: string; + protected _direction: number; + protected _lastCameraAngle: number; + protected _selectedColor: number; + protected _furnitureLift: number; + protected _alphaMultiplier: number; + protected _alphaChanged: boolean; + protected _clickUrl: string; + + protected _cacheDirection: number; + protected _cacheScale: number; + protected _cacheSize: number; + + protected _layerCount: number; + protected _shadowLayerIndex: number; + protected _updatedLayers: boolean[]; + protected _assetNames: string[]; + protected _spriteTags: string[]; + protected _spriteInks: number[]; + protected _spriteAlphas: number[]; + protected _spriteColors: number[]; + protected _spriteMouseCaptures: boolean[]; + protected _spriteXOffsets: number[]; + protected _spriteYOffsets: number[]; + protected _spriteZOffsets: number[]; + + private _animationNumber: number; + + constructor() + { + super(); + + this._data = null; + + this._type = null; + this._direction = 0; + this._lastCameraAngle = NaN; + this._selectedColor = 0; + this._furnitureLift = 0; + this._alphaMultiplier = 1; + this._alphaChanged = false; + this._clickUrl = null; + + this._cacheDirection = -1; + this._cacheScale = 0; + this._cacheSize = -1; + + this._layerCount = 0; + this._shadowLayerIndex = -1; + this._updatedLayers = []; + this._assetNames = []; + this._spriteTags = []; + this._spriteInks = []; + this._spriteAlphas = []; + this._spriteColors = []; + this._spriteMouseCaptures = []; + this._spriteXOffsets = []; + this._spriteYOffsets = []; + this._spriteZOffsets = []; + + this._animationNumber = 0; + } + + public initialize(data: IObjectVisualizationData): boolean + { + this.reset(); + + if(!(data instanceof FurnitureVisualizationData)) return false; + + this._type = data.type; + this._data = data; + + return true; + } + + public dispose(): void + { + super.dispose(); + + this._data = null; + this._updatedLayers = null; + this._assetNames = null; + this._spriteTags = null; + this._spriteInks = null; + this._spriteAlphas = null; + this._spriteColors = null; + this._spriteMouseCaptures = null; + this._spriteXOffsets = null; + this._spriteYOffsets = null; + this._spriteZOffsets = null; + } + + protected reset(): void + { + super.reset(); + + this.setDirection(-1); + + this._data = null; + this._updatedLayers = []; + this._assetNames = []; + this._spriteTags = []; + this._spriteInks = []; + this._spriteAlphas = []; + this._spriteColors = []; + this._spriteMouseCaptures = []; + this._spriteXOffsets = []; + this._spriteYOffsets = []; + this._spriteZOffsets = []; + + this.setSpriteCount(0); + } + + protected resetLayers(scale: number, direction: number): void + { + if((this._cacheDirection === direction) && (this._cacheScale === scale)) return; + + this._updatedLayers = []; + this._assetNames = []; + this._spriteTags = []; + this._spriteInks = []; + this._spriteAlphas = []; + this._spriteColors = []; + this._spriteMouseCaptures = []; + this._spriteXOffsets = []; + this._spriteYOffsets = []; + this._spriteZOffsets = []; + + this._cacheDirection = direction; + this._cacheScale = scale; + this._cacheSize = this.getValidSize(scale); + + this.setLayerCount(((this._data && this._data.getLayerCount(scale)) || 0) + this.getAdditionalLayerCount()); + } + + public update(geometry: IRoomGeometry, time: number, update: boolean, skipUpdate: boolean): void + { + if(!geometry) return; + + const scale = geometry.scale; + let updateSprites = false; + + if(this.updateObject(scale, geometry.direction.x)) updateSprites = true; + + if(this.updateModel(scale)) updateSprites = true; + + let number = 0; + + if(skipUpdate) + { + this._animationNumber = (this._animationNumber | this.updateAnimation(scale)); + } + else + { + number = this.updateAnimation(scale) | this._animationNumber; + + this._animationNumber = 0; + } + + if(updateSprites || (number !== 0)) + { + this.updateSprites(scale, updateSprites, number); + + this._scale = scale; + + this.updateSpriteCounter++; + } + } + + protected updateObject(scale: number, direction: number): boolean + { + if(!this.object) return false; + + if((this.updateObjectCounter === this.object.updateCounter) && (scale === this._scale) && (this._lastCameraAngle === direction)) return false; + + let offsetDirection = (this.object.getDirection().x - (direction + 135)); + + offsetDirection = ((((offsetDirection) % 360) + 360) % 360); + + if(this._data) + { + const validDirection = this._data.getValidDirection(scale, offsetDirection); + + this.setDirection(validDirection); + } + + this._lastCameraAngle = direction; + this._scale = scale; + + this.updateObjectCounter = this.object.updateCounter; + + this.resetLayers(scale, this._direction); + + return true; + } + + protected updateModel(scale: number): boolean + { + const model = this.object && this.object.model; + + if(!model) return false; + + if(this.updateModelCounter === model.updateCounter) return false; + + this._selectedColor = model.getValue(RoomObjectVariable.FURNITURE_COLOR); + this._clickUrl = model.getValue(RoomObjectVariable.FURNITURE_AD_URL); + this._furnitureLift = (model.getValue(RoomObjectVariable.FURNITURE_LIFT_AMOUNT) || 0); + + let alphaMultiplier = model.getValue(RoomObjectVariable.FURNITURE_ALPHA_MULTIPLIER); + + if(isNaN(alphaMultiplier)) alphaMultiplier = 1; + + if(this._alphaMultiplier !== alphaMultiplier) + { + this._alphaMultiplier = alphaMultiplier; + + this._alphaChanged = true; + } + + this.updateModelCounter = model.updateCounter; + + return true; + } + + protected updateSprites(scale: number, update: boolean, animation: number): void + { + if(this._layerCount !== this.totalSprites) this.setSpriteCount(this._layerCount); + + if(update) + { + let layerId = (this.totalSprites - 1); + + while(layerId >= 0) + { + this.updateSprite(scale, layerId); + + layerId--; + } + } + else + { + let layerId = 0; + + while(animation > 0) + { + if(animation) this.updateSprite(scale, layerId); + + layerId++; + animation = (animation >> 1); + } + } + + this._alphaChanged = false; + } + + protected updateSprite(scale: number, layerId: number): void + { + const assetName = this.getSpriteAssetName(scale, layerId); + const sprite = this.getSprite(layerId); + + if(assetName && sprite) + { + const assetData = this.getAsset(assetName, layerId); + + if(assetData && assetData.texture) + { + sprite.visible = true; + sprite.type = this._type; + sprite.texture = assetData.texture; + sprite.flipH = assetData.flipH; + sprite.flipV = assetData.flipV; + sprite.direction = this._direction; + + let relativeDepth = 0; + + if(layerId !== this._shadowLayerIndex) + { + sprite.tag = this.getLayerTag(scale, this._direction, layerId); + sprite.alpha = this.getLayerAlpha(scale, this._direction, layerId); + sprite.color = this.getLayerColor(scale, layerId, this._selectedColor); + sprite.offsetX = (assetData.offsetX + this.getLayerXOffset(scale, this._direction, layerId)); + sprite.offsetY = (assetData.offsetY + this.getLayerYOffset(scale, this._direction, layerId)); + sprite.blendMode = this.getLayerInk(scale, this._direction, layerId); + sprite.alphaTolerance = (this.getLayerIgnoreMouse(scale, this._direction, layerId) ? AlphaTolerance._Str_9268 : AlphaTolerance._Str_9735); + + relativeDepth = this.getLayerZOffset(scale, this._direction, layerId); + relativeDepth = (relativeDepth - (layerId * 0.001)); + } + else + { + sprite.offsetX = assetData.offsetX; + sprite.offsetY = (assetData.offsetY + this.getLayerYOffset(scale, this._direction, layerId)); + sprite.alpha = (48 * this._alphaMultiplier); + sprite.alphaTolerance = AlphaTolerance._Str_9268; + + relativeDepth = 1; + } + + sprite.relativeDepth = (relativeDepth * FurnitureVisualization.DEPTH_MULTIPLIER); + sprite.name = assetName; + sprite._Str_3582 = this.getLibraryAssetNameForSprite(assetData, sprite); + sprite.posture = this.getPostureForAsset(scale, assetData.source); + sprite.clickHandling = false; + } + else + { + this.resetSprite(sprite); + } + } + else + { + if(sprite) this.resetSprite(sprite); + } + } + + protected getLibraryAssetNameForSprite(asset: IGraphicAsset, sprite: IRoomObjectSprite): string + { + return asset.source; + } + + protected getPostureForAssetFile(scale: number, _arg_2: string): string + { + return null; + } + + private resetSprite(sprite: IRoomObjectSprite): void + { + if(!sprite) return; + + sprite.texture = null; + sprite.offsetX = 0; + sprite.offsetY = 0; + sprite.flipH = false; + sprite.flipV = false; + sprite.relativeDepth = 0; + } + + protected getSpriteAssetName(scale: number, layerId: number): string + { + if(!this._data || (layerId >= FurnitureVisualizationData.LAYER_LETTERS.length)) return ''; + + let assetName = this._assetNames[layerId]; + let updated = this._updatedLayers[layerId]; + + if(!assetName || !assetName.length) + { + assetName = this.cacheSpriteAssetName(scale, layerId, true); + updated = (this._cacheSize !== 1); + } + + if(updated) assetName += this.getFrameNumber(scale, layerId); + + return assetName; + } + + protected cacheSpriteAssetName(scale: number, layerId: number, cache: boolean): string + { + const type = this._type; + const size = (cache) ? this._cacheSize : this.getValidSize(scale); + let layerCode = ''; + const isntIcon = (size !== 1); + + if(layerId !== this._shadowLayerIndex) + { + layerCode = FurnitureVisualizationData.LAYER_LETTERS[layerId] || ''; + } + else + { + layerCode = 'sd'; + } + + if(layerCode === '') return null; + + const assetName = (this._type + ((isntIcon) ? ('_' + size + '_' + layerCode + '_' + this._direction + '_') : ('_icon_' + layerCode))); + + if(cache) + { + this._assetNames[layerId] = assetName; + this._updatedLayers[layerId] = isntIcon; + } + + return assetName; + } + + protected getLayerTag(scale: number, direction: number, layerId: number): string + { + const existing = this._spriteTags[layerId]; + + if(existing !== undefined) return existing; + + if(!this._data) return LayerData.DEFAULT_TAG; + + const tag = this._data.getLayerTag(scale, direction, layerId); + + this._spriteTags[layerId] = tag; + + return tag; + } + + protected getLayerInk(scale: number, direction: number, layerId: number): number + { + const existing = this._spriteInks[layerId]; + + if(existing !== undefined) return existing; + + if(!this._data) return LayerData.DEFAULT_INK; + + const ink = this._data.getLayerInk(scale, direction, layerId); + + this._spriteInks[layerId] = ink; + + return ink; + } + + protected getLayerAlpha(scale: number, direction: number, layerId: number): number + { + if(!this._alphaChanged) + { + const existing = this._spriteAlphas[layerId]; + + if(existing !== undefined) return existing; + } + + if(!this._data) return LayerData.DEFAULT_ALPHA; + + let alpha = this._data.getLayerAlpha(scale, direction, layerId); + + if(this._alphaMultiplier !== null) alpha = (alpha * this._alphaMultiplier); + + this._spriteAlphas[layerId] = alpha; + + return alpha; + } + + protected getLayerColor(scale: number, layerId: number, colorId: number): number + { + const existing = this._spriteColors[layerId]; + + if(existing !== undefined) return existing; + + if(!this._data) return ColorData.DEFAULT_COLOR; + + const color = this._data.getLayerColor(scale, layerId, colorId); + + this._spriteColors[layerId] = color; + + return color; + } + + protected getLayerIgnoreMouse(scale: number, direction: number, layerId: number): boolean + { + const existing = this._spriteMouseCaptures[layerId]; + + if(existing !== undefined) return existing; + + if(!this._data) return LayerData.DEFAULT_IGNORE_MOUSE; + + const ignoreMouse = this._data.getLayerIgnoreMouse(scale, direction, layerId); + + this._spriteMouseCaptures[layerId] = ignoreMouse; + + return ignoreMouse; + } + + protected getLayerXOffset(scale: number, direction: number, layerId: number): number + { + const existing = this._spriteXOffsets[layerId]; + + if(existing !== undefined) return existing; + + if(!this._data) return LayerData.DEFAULT_XOFFSET; + + const xOffset = this._data.getLayerXOffset(scale, direction, layerId); + + this._spriteXOffsets[layerId] = xOffset; + + return xOffset; + } + + protected getLayerYOffset(scale: number, direction: number, layerId: number): number + { + if(layerId === this._shadowLayerIndex) return Math.ceil((this._furnitureLift * (64 / 2))); + + const existing = this._spriteYOffsets[layerId]; + + if(existing !== undefined) return existing; + + if(!this._data) return LayerData.DEFAULT_YOFFSET; + + const yOffset = this._data.getLayerYOffset(scale, direction, layerId); + + this._spriteYOffsets[layerId] = yOffset; + + return yOffset; + } + + protected getLayerZOffset(scale: number, direction: number, layerId: number): number + { + const existing = this._spriteZOffsets[layerId]; + + if(existing !== undefined) return existing; + + if(!this._data) return LayerData.DEFAULT_ZOFFSET; + + const zOffset = this._data.getLayerZOffset(scale, direction, layerId); + + this._spriteZOffsets[layerId] = zOffset; + + return zOffset; + } + + protected getValidSize(scale: number): number + { + if(!this._data) return scale; + + return this._data.getValidSize(scale); + } + + protected setLayerCount(count: number): void + { + this._layerCount = count; + this._shadowLayerIndex = count - this.getAdditionalLayerCount(); + } + + protected setDirection(direction: number): void + { + if(this._direction === direction) return; + + this._direction = direction; + } + + protected getAdditionalLayerCount(): number + { + return 1; + } + + protected updateAnimation(scale: number): number + { + return 0; + } + + protected getFrameNumber(scale: number, layerId: number): number + { + return 0; + } + + protected getPostureForAsset(scale: number, name: string): string + { + return null; + } + + public getAsset(name: string, layerId: number = -1): IGraphicAsset + { + if(!this.asset) return null; + + return this.asset.getAsset(name); + } + + protected get direction(): number + { + return this._direction; + } +} diff --git a/src/nitro/room/object/visualization/furniture/FurnitureVisualizationData.ts b/src/nitro/room/object/visualization/furniture/FurnitureVisualizationData.ts new file mode 100644 index 00000000..4cd66118 --- /dev/null +++ b/src/nitro/room/object/visualization/furniture/FurnitureVisualizationData.ts @@ -0,0 +1,295 @@ +import { IAssetData } from '../../../../../core/asset/interfaces'; +import { IAssetVisualizationData } from '../../../../../core/asset/interfaces/visualization'; +import { IObjectVisualizationData } from '../../../../../room/object/visualization/IRoomObjectVisualizationData'; +import { ColorData } from '../data/ColorData'; +import { LayerData } from '../data/LayerData'; +import { SizeData } from '../data/SizeData'; + +export class FurnitureVisualizationData implements IObjectVisualizationData +{ + public static LAYER_LETTERS: string[] = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']; + + private _type: string; + private _sizes: number[]; + private _sizeDatas: Map; + private _lastSize: number; + private _lastSizeScale: number; + private _lastSizeData: SizeData; + private _lastSizeDataScale: number; + + constructor() + { + this._type = ''; + this._sizes = []; + this._sizeDatas = new Map(); + this._lastSize = -1; + this._lastSizeScale = -1; + this._lastSizeData = null; + this._lastSizeDataScale = -1; + } + + public initialize(asset: IAssetData): boolean + { + this.reset(); + + if(!asset) return false; + + this._type = asset.name; + + if(!this.defineVisualizations(asset.visualizations)) + { + this.reset(); + + return false; + } + + return true; + } + + public dispose(): void + { + if(this._sizeDatas && this._sizeDatas.size) + { + for(const size of this._sizeDatas.values()) size && size.dispose(); + + this._sizeDatas = null; + } + + this._lastSizeData = null; + this._sizes = null; + } + + private reset(): void + { + this._type = ''; + + if(this._sizeDatas && this._sizeDatas.size) + { + for(const size of this._sizeDatas.values()) size && size.dispose(); + } + + this._sizeDatas.clear(); + + this._sizes = []; + this._lastSizeData = null; + this._lastSizeDataScale = -1; + } + + protected createSizeData(scale: number, layerCount: number, angle: number): SizeData + { + return new SizeData(layerCount, angle); + } + + protected defineVisualizations(visualizations: IAssetVisualizationData[]): boolean + { + if(!visualizations) return false; + + for(const visualizationId in visualizations) + { + const visualization = visualizations[visualizationId]; + + const layerCount = visualization.layerCount; + const angle = visualization.angle; + + let size = visualization.size; + + if(size < 1) size = 1; + + if(this._sizeDatas.get(size)) return false; + + const sizeData = this.createSizeData(size, layerCount, angle); + + if(!sizeData) return false; + + for(const key in visualization) + { + //@ts-ignore + const data = visualization[key]; + + if(!this.processVisualElement(sizeData, key, data)) + { + sizeData.dispose(); + + return false; + } + } + + this._sizeDatas.set(size, sizeData); + + this._sizes.push(size); + } + + this._sizes.sort(); + + return true; + } + + protected processVisualElement(sizeData: SizeData, key: string, data: any): boolean + { + if(!sizeData || !key || !data) return false; + + switch(key) + { + case 'layers': + if(!sizeData.processLayers(data)) return false; + break; + case 'directions': + if(!sizeData.processDirections(data)) return false; + break; + case 'colors': + if(!sizeData.processColors(data)) return false; + break; + } + + return true; + } + + public getValidSize(scale: number): number + { + if(scale === this._lastSizeScale) return this._lastSize; + + const sizeIndex = this.getSizeIndex(scale); + + let newScale = -1; + + if(sizeIndex < this._sizes.length) newScale = this._sizes[sizeIndex]; + + this._lastSizeScale = scale; + this._lastSize = newScale; + + return newScale; + } + + private getSizeIndex(size: number): number + { + if(size <= 0) return 0; + + let index = 0; + let iterator = 1; + + while(iterator < this._sizes.length) + { + if(this._sizes[iterator] > size) + { + if((this._sizes[iterator] / size) < (size / this._sizes[(iterator - 1)])) index = iterator; + + break; + } + + index = iterator; + + iterator++; + } + + return index; + } + + protected getSizeData(size: number): SizeData + { + if(size === this._lastSizeDataScale) return this._lastSizeData; + + const sizeIndex = this.getSizeIndex(size); + + if(sizeIndex < this._sizes.length) this._lastSizeData = this._sizeDatas.get(this._sizes[sizeIndex]); + else this._lastSizeData = null; + + this._lastSizeDataScale = size; + + return this._lastSizeData; + } + + public getLayerCount(scale: number): number + { + const size = this.getSizeData(scale); + + if(!size) return LayerData.DEFAULT_COUNT; + + return size.layerCount; + } + + public getValidDirection(scale: number, direction: number): number + { + const size = this.getSizeData(scale); + + if(!size) return LayerData.DEFAULT_DIRECTION; + + return size.getValidDirection(direction); + } + + public getLayerTag(scale: number, direction: number, layerId: number): string + { + const size = this.getSizeData(scale); + + if(!size) return LayerData.DEFAULT_TAG; + + return size.getLayerTag(direction, layerId); + } + + public getLayerInk(scale: number, direction: number, layerId: number): number + { + const size = this.getSizeData(scale); + + if(!size) return LayerData.DEFAULT_INK; + + return size.getLayerInk(direction, layerId); + } + + public getLayerAlpha(scale: number, direction: number, layerId: number): number + { + const size = this.getSizeData(scale); + + if(!size) return LayerData.DEFAULT_ALPHA; + + return size.getLayerAlpha(direction, layerId); + } + + public getLayerColor(scale: number, layerId: number, colorId: number): number + { + const size = this.getSizeData(scale); + + if(!size) return ColorData.DEFAULT_COLOR; + + return size.getLayerColor(layerId, colorId); + } + + public getLayerIgnoreMouse(scale: number, direction: number, layerId: number): boolean + { + const size = this.getSizeData(scale); + + if(!size) return LayerData.DEFAULT_IGNORE_MOUSE; + + return size.getLayerIgnoreMouse(direction, layerId); + } + + public getLayerXOffset(scale: number, direction: number, layerId: number): number + { + const size = this.getSizeData(scale); + + if(!size) return LayerData.DEFAULT_XOFFSET; + + return size.getLayerXOffset(direction, layerId); + } + + public getLayerYOffset(scale: number, direction: number, layerId: number): number + { + const size = this.getSizeData(scale); + + if(!size) return LayerData.DEFAULT_YOFFSET; + + return size.getLayerYOffset(direction, layerId); + } + + public getLayerZOffset(scale: number, direction: number, layerId: number): number + { + const size = this.getSizeData(scale); + + if(!size) return LayerData.DEFAULT_ZOFFSET; + + return size.getLayerZOffset(direction, layerId); + } + + public get type(): string + { + return this._type; + } +} diff --git a/src/nitro/room/object/visualization/furniture/FurnitureVoteCounterVisualization.ts b/src/nitro/room/object/visualization/furniture/FurnitureVoteCounterVisualization.ts new file mode 100644 index 00000000..8f3d3df6 --- /dev/null +++ b/src/nitro/room/object/visualization/furniture/FurnitureVoteCounterVisualization.ts @@ -0,0 +1,51 @@ +import { RoomObjectVariable } from '../../RoomObjectVariable'; +import { FurnitureAnimatedVisualization } from './FurnitureAnimatedVisualization'; + +export class FurnitureVoteCounterVisualization extends FurnitureAnimatedVisualization +{ + private static ONES_SPRITE: string = 'ones_sprite'; + private static TENS_SPRITE: string = 'tens_sprite'; + private static HUNDREDS_SPRITE: string = 'hundreds_sprite'; + private static _Str_17839: number = -1; + + protected updateObject(scale: number, direction: number): boolean + { + super.updateObject(scale, direction); + + return true; + } + + protected getFrameNumber(scale: number, layerId: number): number + { + const result = this.object.model.getValue(RoomObjectVariable.FURNITURE_VOTE_COUNTER_COUNT); + const tag = this.getLayerTag(scale, this.direction, layerId); + + switch(tag) + { + case FurnitureVoteCounterVisualization.ONES_SPRITE: return (result % 10); + case FurnitureVoteCounterVisualization.TENS_SPRITE: return ((result / 10) % 10); + case FurnitureVoteCounterVisualization.HUNDREDS_SPRITE: return ((result / 100) % 10); + default: return super.getFrameNumber(scale, layerId); + } + } + + protected getLayerAlpha(scale: number, direction: number, layerId: number): number + { + const result = this.object.model.getValue(RoomObjectVariable.FURNITURE_VOTE_COUNTER_COUNT); + + if(result === FurnitureVoteCounterVisualization._Str_17839) + { + const tag = this.getLayerTag(scale, direction, layerId); + + switch(tag) + { + case FurnitureVoteCounterVisualization.ONES_SPRITE: + case FurnitureVoteCounterVisualization.TENS_SPRITE: + case FurnitureVoteCounterVisualization.HUNDREDS_SPRITE: + return 0; + } + } + + return super.getLayerAlpha(scale, direction, layerId); + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/furniture/FurnitureVoteMajorityVisualization.ts b/src/nitro/room/object/visualization/furniture/FurnitureVoteMajorityVisualization.ts new file mode 100644 index 00000000..60681cda --- /dev/null +++ b/src/nitro/room/object/visualization/furniture/FurnitureVoteMajorityVisualization.ts @@ -0,0 +1,45 @@ +import { RoomObjectVariable } from '../../RoomObjectVariable'; +import { FurnitureAnimatedVisualization } from './FurnitureAnimatedVisualization'; + +export class FurnitureVoteMajorityVisualization extends FurnitureAnimatedVisualization +{ + private static ONES_SPRITE: string = 'ones_sprite'; + private static TENS_SPRITE: string = 'tens_sprite'; + private static HUNDREDS_SPRITE: string = 'hundreds_sprite'; + private static _Str_16109: number[] = [-1, 1]; + private static _Str_17618: number = -1; + + protected getFrameNumber(scale: number, layerId: number): number + { + const result = this.object.model.getValue(RoomObjectVariable.FURNITURE_VOTE_MAJORITY_RESULT); + const tag = this.getLayerTag(scale, this.direction, layerId); + + switch(tag) + { + case FurnitureVoteMajorityVisualization.ONES_SPRITE: return (result % 10); + case FurnitureVoteMajorityVisualization.TENS_SPRITE: return ((result / 10) % 10); + case FurnitureVoteMajorityVisualization.HUNDREDS_SPRITE: return ((result / 100) % 10); + default: return super.getFrameNumber(scale, layerId); + } + } + + protected getLayerAlpha(scale: number, direction: number, layerId: number): number + { + const result = this.object.model.getValue(RoomObjectVariable.FURNITURE_VOTE_MAJORITY_RESULT); + + if(((!(FurnitureVoteMajorityVisualization._Str_16109.indexOf(this.object.getState(0)) === -1)) || (result === FurnitureVoteMajorityVisualization._Str_17618))) + { + const tag = this.getLayerTag(scale, direction, layerId); + + switch(tag) + { + case FurnitureVoteMajorityVisualization.ONES_SPRITE: + case FurnitureVoteMajorityVisualization.TENS_SPRITE: + case FurnitureVoteMajorityVisualization.HUNDREDS_SPRITE: + return 0; + } + } + + return super.getLayerAlpha(scale, direction, layerId); + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/furniture/FurnitureWaterAreaVisualization.ts b/src/nitro/room/object/visualization/furniture/FurnitureWaterAreaVisualization.ts new file mode 100644 index 00000000..c40f65c1 --- /dev/null +++ b/src/nitro/room/object/visualization/furniture/FurnitureWaterAreaVisualization.ts @@ -0,0 +1,6 @@ +import { FurnitureAnimatedVisualization } from './FurnitureAnimatedVisualization'; + +export class FurnitureWaterAreaVisualization extends FurnitureAnimatedVisualization +{ + +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/furniture/FurnitureYoutubeVisualization.ts b/src/nitro/room/object/visualization/furniture/FurnitureYoutubeVisualization.ts new file mode 100644 index 00000000..91b9edf1 --- /dev/null +++ b/src/nitro/room/object/visualization/furniture/FurnitureYoutubeVisualization.ts @@ -0,0 +1,20 @@ +import { FurnitureDynamicThumbnailVisualization } from './FurnitureDynamicThumbnailVisualization'; + +export class FurnitureYoutubeVisualization extends FurnitureDynamicThumbnailVisualization +{ + protected static THUMBNAIL_URL: string = 'THUMBNAIL_URL'; + + protected getThumbnailURL(): string + { + if(!this.object) return null; + + return null; + + // const data = this.object.model.getValue(RoomObjectVariable.FURNITURE_DATA); + // const url = this.object.model.getValue(RoomObjectVariable.SESSION_URL_PREFIX); + + // if(!data || !url) return null; + + // return (url + FurnitureYoutubeVisualization.THUMBNAIL); + } +} diff --git a/src/nitro/room/object/visualization/pet/PetVisualization.ts b/src/nitro/room/object/visualization/pet/PetVisualization.ts new file mode 100644 index 00000000..4d68428b --- /dev/null +++ b/src/nitro/room/object/visualization/pet/PetVisualization.ts @@ -0,0 +1,561 @@ +import { IObjectVisualizationData } from '../../../../../room/object/visualization/IRoomObjectVisualizationData'; +import { IGraphicAsset } from '../../../../../room/object/visualization/utils/IGraphicAsset'; +import { IRoomGeometry } from '../../../../../room/utils/IRoomGeometry'; +import { RoomObjectVariable } from '../../RoomObjectVariable'; +import { RoomObjectVisualizationType } from '../../RoomObjectVisualizationType'; +import { AnimationData } from '../data/AnimationData'; +import { AnimationStateData } from '../data/AnimationStateData'; +import { DirectionData } from '../data/DirectionData'; +import { LayerData } from '../data/LayerData'; +import { FurnitureAnimatedVisualization } from '../furniture/FurnitureAnimatedVisualization'; +import { FurnitureVisualizationData } from '../furniture/FurnitureVisualizationData'; +import { PetVisualizationData } from './PetVisualizationData'; + +export class PetVisualization extends FurnitureAnimatedVisualization +{ + public static TYPE: string = RoomObjectVisualizationType.PET_ANIMATED; + + private static HEAD: string = 'head'; + private static SADDLE: string = 'saddle'; + private static HAIR: string = 'hair'; + private static _Str_7490: number = 1; + private static _Str_13277: number = 1000; + private static PET_EXPERIENCE_BUBBLE_PNG: string = 'pet_experience_bubble_png'; + private static _Str_16082: number = 0; + private static _Str_17658: number = 1; + private static _Str_16677: number = 2; + + protected _data: PetVisualizationData; + + private _posture: string; + private _gesture: string; + private _isSleeping: boolean; + private _headDirection: number; + private _headOnly: boolean; + private _nonHeadSprites: boolean[]; + private _headSprites: boolean[]; + private _saddleSprites: boolean[]; + private _animationOver: boolean; + private _paletteIndex: number; + private _paletteName: string; + private _customLayerIds: number[]; + private _customPartIds: number[]; + private _customPaletteIds: number[]; + private _isRiding: boolean; + private _color: number; + + private _previousAnimationDirection: number; + private _animationStates: AnimationStateData[]; + + constructor() + { + super(); + + this._data = null; + + this._posture = ''; + this._gesture = ''; + this._isSleeping = false; + this._headDirection = -1; + this._headOnly = false; + this._nonHeadSprites = []; + this._headSprites = []; + this._saddleSprites = []; + this._animationOver = false; + this._paletteIndex = -1; + this._paletteName = ''; + this._customLayerIds = []; + this._customPartIds = []; + this._customPaletteIds = []; + this._isRiding = false; + this._color = 0xFFFFFF; + + this._previousAnimationDirection = -1; + this._animationStates = []; + + while(this._animationStates.length < PetVisualization._Str_16677) this._animationStates.push(new AnimationStateData()); + } + + public initialize(data: IObjectVisualizationData): boolean + { + if(!(data instanceof PetVisualizationData)) return false; + + return super.initialize(data); + } + + public dispose(): void + { + super.dispose(); + + if(this._animationStates) + { + while(this._animationStates.length) + { + const animationState = this._animationStates[0]; + + if(animationState) animationState.dispose(); + + this._animationStates.pop(); + } + + this._animationStates = null; + } + } + + protected getAnimationId(animationData: AnimationStateData): number + { + return animationData.animationId; + } + + public update(geometry: IRoomGeometry, time: number, update: boolean, skipUpdate: boolean): void + { + super.update(geometry, time, update, skipUpdate); + + // update experience + } + + protected updateModel(scale: number): boolean + { + const model = this.object && this.object.model; + + if(!model) return false; + + if(this.updateModelCounter === model.updateCounter) return false; + + // _local_4 = _local_3.getString(RoomObjectVariableEnum.FIGURE_POSTURE); + // _local_5 = _local_3.getString(RoomObjectVariableEnum.FIGURE_GESTURE); + // _local_6 = _local_3.getNumber(RoomObjectVariableEnum.FIGURE_POSTURE); + // if (!isNaN(_local_6)) + // { + // _local_16 = this._animationData._Str_17398(_Str_3289); + // if (_local_16 > 0) + // { + // _local_4 = this._animationData._Str_14207(_Str_3289, (_local_6 % _local_16), true); + // _local_5 = null; + // } + // } + // _local_7 = _local_3.getNumber(RoomObjectVariableEnum.FIGURE_GESTURE); + // if (!isNaN(_local_7)) + // { + // _local_17 = this._animationData._Str_16869(_Str_3289); + // if (_local_17 > 0) + // { + // _local_5 = this._animationData._Str_17844(_Str_3289, (_local_7 % _local_17)); + // } + // } + // this._Str_14314(_local_4, _local_5); + + + + const posture = model.getValue(RoomObjectVariable.FIGURE_POSTURE); + const gesture = model.getValue(RoomObjectVariable.FIGURE_GESTURE); + const tempPosture = model.getValue(RoomObjectVariable.FIGURE_POSTURE); + + this.setPostureAndGesture(posture, gesture); + + let alphaMultiplier = (model.getValue(RoomObjectVariable.FURNITURE_ALPHA_MULTIPLIER) || null); + + if(alphaMultiplier === null || isNaN(alphaMultiplier)) alphaMultiplier = 1; + + if(this._alphaMultiplier !== alphaMultiplier) + { + this._alphaMultiplier = alphaMultiplier; + + this._alphaChanged = true; + } + + this._isSleeping = (model.getValue(RoomObjectVariable.FIGURE_SLEEP) > 0); + + const headDirection = model.getValue(RoomObjectVariable.HEAD_DIRECTION); + + if(!isNaN(headDirection) && this._data.isAllowedToTurnHead) + { + this._headDirection = headDirection; + } + else + { + this._headDirection = this.object.getDirection().x; + } + + const customPaletteIndex = model.getValue(RoomObjectVariable.PET_PALETTE_INDEX); + const customLayerIds = model.getValue(RoomObjectVariable.PET_CUSTOM_LAYER_IDS); + const customPartIds = model.getValue(RoomObjectVariable.PET_CUSTOM_PARTS_IDS); + const customPaletteIds = model.getValue(RoomObjectVariable.PET_CUSTOM_PALETTE_IDS); + const isRiding = model.getValue(RoomObjectVariable.PET_IS_RIDING); + const headOnly = model.getValue(RoomObjectVariable.PET_HEAD_ONLY); + const color = model.getValue(RoomObjectVariable.PET_COLOR); + + if(customPaletteIndex !== this._paletteIndex) + { + this._paletteIndex = customPaletteIndex; + this._paletteName = this._paletteIndex.toString(); + } + + this._customLayerIds = (customLayerIds) ? customLayerIds : []; + this._customPartIds = (customPartIds) ? customPartIds : []; + this._customPaletteIds = (customPaletteIds) ? customPaletteIds : []; + this._isRiding = (!isNaN(isRiding) && (isRiding > 0)); + this._headOnly = (!isNaN(headOnly) && (headOnly > 0)); + + if(!isNaN(color) && this._color !== color) this._color = color; + + this.updateModelCounter = model.updateCounter; + + return true; + } + + protected updateAnimation(scale: number): number + { + if(this.object) + { + const direction = this.object.getDirection().x; + + if(direction !== this._previousAnimationDirection) + { + this._previousAnimationDirection = direction; + + this.resetAllAnimationFrames(); + } + } + + return super.updateAnimation(scale); + } + + protected setPostureAndGesture(posture: string, gesture: string): void + { + if(posture !== this._posture) + { + this._posture = posture; + + this._Str_16058(PetVisualization._Str_16082, this._data.postureToAnimation(this._scale, posture)); + } + + if(this._data._Str_18284(this._scale, posture)) gesture = null; + + if(gesture !== this._gesture) + { + this._gesture = gesture; + + this._Str_16058(PetVisualization._Str_17658, this._data.gestureToAnimation(this._scale, gesture)); + } + } + + private _Str_22634(k: number): AnimationStateData + { + if((k >= 0) && (k < this._animationStates.length)) return this._animationStates[k]; + + return null; + } + + private _Str_16058(k: number, _arg_2: number): void + { + const animationStateData = this._Str_22634(k); + + if(animationStateData) + { + if(this.setSubAnimation(animationStateData, _arg_2)) this._animationOver = false; + } + } + + protected resetAllAnimationFrames(): void + { + this._animationOver = false; + + let index = (this._animationStates.length - 1); + + while(index >= 0) + { + const stateData = this._animationStates[index]; + + if(stateData) stateData.setLayerCount(this.animatedLayerCount); + + index--; + } + } + + protected updateAnimations(scale: number): number + { + if(this._animationOver) return 0; + + let animationOver = true; + let _local_3 = 0; + let index = 0; + + while(index < this._animationStates.length) + { + const stateData = this._animationStates[index]; + + if(stateData) + { + if(!stateData.animationOver) + { + const _local_6 = this.updateFramesForAnimation(stateData, scale); + + _local_3 = (_local_3 | _local_6); + + if(!stateData.animationOver) + { + animationOver = false; + } + else + { + if(AnimationData.isTransitionFromAnimation(stateData.animationId) || AnimationData.isTransitionToAnimation(stateData.animationId)) + { + this._Str_16058(index, stateData.animationAfterTransitionId); + + animationOver = false; + } + } + } + } + + index++; + } + + this._animationOver = animationOver; + + return _local_3; + } + + protected getSpriteAssetName(scale: number, layerId: number): string + { + if(this._headOnly && this._Str_24824(layerId)) return null; + + if(this._isRiding && this._parser3(layerId)) return null; + + const totalSprites = this.totalSprites; + + if(layerId < (totalSprites - PetVisualization._Str_7490)) + { + const validScale = this.getValidSize(scale); + + if(layerId < (totalSprites - (1 + PetVisualization._Str_7490))) + { + if(layerId >= FurnitureVisualizationData.LAYER_LETTERS.length) return null; + + const layerLetter = FurnitureVisualizationData.LAYER_LETTERS[layerId]; + + if(validScale === 1) return (this._type + '_icon_' + layerLetter); + + return (this._type + '_' + validScale + '_' + layerLetter + '_' + this.getDirection(scale, layerId) + '_' + this.getFrameNumber(validScale, layerId)); + } + + return (this._type + '_' + validScale + '_sd_' + this.getDirection(scale, layerId) + '_0'); + } + + return null; + } + + protected getLayerColor(scale: number, layerId: number, colorId: number): number + { + if(layerId < (this.totalSprites - PetVisualization._Str_7490)) return this._color; + + return 0xFFFFFF; + } + + protected getLayerXOffset(scale: number, direction: number, layerId: number): number + { + let offset = super.getLayerXOffset(scale, direction, layerId); + let index = (this._animationStates.length - 1); + + while(index >= 0) + { + const stateData = this._animationStates[index]; + + if(stateData) + { + const frame = stateData.getFrame(layerId); + + if(frame) offset += frame.x; + } + + index--; + } + + return offset; + } + + protected getLayerYOffset(scale: number, direction: number, layerId: number): number + { + let offset = super.getLayerYOffset(scale, direction, layerId); + let index = (this._animationStates.length - 1); + + while(index >= 0) + { + const stateData = this._animationStates[index]; + + if(stateData) + { + const frame = stateData.getFrame(layerId); + + if(frame) offset += frame.y; + } + + index--; + } + + return offset; + } + + protected getLayerZOffset(scale: number, direction: number, layerId: number): number + { + if(!this._data) return LayerData.DEFAULT_ZOFFSET; + + return this._data.getLayerZOffset(scale, this.getDirection(scale, layerId), layerId); + } + + private getDirection(scale: number, layerId: number): number + { + if(!this._Str_23973(layerId)) return this._direction; + + return this._data.getValidDirection(scale, this._headDirection); + } + + protected getFrameNumber(scale: number, layerId: number): number + { + let index = (this._animationStates.length - 1); + + while(index >= 0) + { + const stateData = this._animationStates[index]; + + if(stateData) + { + const frame = stateData.getFrame(layerId); + + if(frame) return frame.id; + } + + index--; + } + + return super.getFrameNumber(scale, layerId); + } + + private _Str_23973(layerId: number): boolean + { + if(this._headSprites[layerId] === undefined) + { + const isHead = (this._data.getLayerTag(this._scale, DirectionData._Str_9471, layerId) === PetVisualization.HEAD); + const isHair = (this._data.getLayerTag(this._scale, DirectionData._Str_9471, layerId) === PetVisualization.HAIR); + + if(isHead || isHair) this._headSprites[layerId] = true; + else this._headSprites[layerId] = false; + } + + return this._headSprites[layerId]; + } + + private _Str_24824(layerId: number): boolean + { + if(this._nonHeadSprites[layerId] === undefined) + { + if(layerId < (this.totalSprites - (1 + PetVisualization._Str_7490))) + { + const tag = this._data.getLayerTag(this._scale, DirectionData._Str_9471, layerId); + + if(((tag && (tag.length > 0)) && (tag !== PetVisualization.HEAD)) && (tag !== PetVisualization.HAIR)) + { + this._nonHeadSprites[layerId] = true; + } + else + { + this._nonHeadSprites[layerId] = false; + } + } + else + { + this._nonHeadSprites[layerId] = true; + } + } + + return this._nonHeadSprites[layerId]; + } + + private _parser3(layerId: number): boolean + { + if(this._saddleSprites[layerId] === undefined) + { + if(this._data.getLayerTag(this._scale, DirectionData._Str_9471, layerId) === PetVisualization.SADDLE) + { + this._saddleSprites[layerId] = true; + } + else + { + this._saddleSprites[layerId] = false; + } + } + + return this._saddleSprites[layerId]; + } + + public getAsset(name: string, layerId: number = -1): IGraphicAsset + { + if(!this.asset) return null; + + const layerIndex = this._customLayerIds.indexOf(layerId); + let paletteName = this._paletteName; + let partId = -1; + let paletteId = -1; + + if(layerIndex > -1) + { + partId = this._customPartIds[layerIndex]; + paletteId = this._customPaletteIds[layerIndex]; + paletteName = ((paletteId > -1) ? paletteId.toString() : this._paletteName); + } + + if(!(isNaN(partId)) && (partId > -1)) + { + name = (name + '_' + partId); + } + + return this.asset.getAssetWithPalette(name, paletteName); + } + + protected getAdditionalLayerCount(): number + { + return super.getAdditionalLayerCount() + PetVisualization._Str_7490; + } + + protected setLayerCount(count: number): void + { + super.setLayerCount(count); + + this._headSprites = []; + } + + protected getPostureForAsset(scale: number, name: string): string + { + const parts = name.split('_'); + let length = parts.length; + let i = 0; + + while(i < parts.length) + { + if((parts[i] === '64') || (parts[i] === '32')) + { + length = (i + 3); + + break; + } + + i++; + } + + let posture: string = null; + + if(length < parts.length) + { + let part = parts[length]; + + part = part.split('@')[0]; + + posture = this._data._Str_14207(scale, (parseInt(part) / 100), false); + + if(!posture) posture = this._data._Str_17976(scale, (parseInt(part) / 100)); + } + + return posture; + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/pet/PetVisualizationData.ts b/src/nitro/room/object/visualization/pet/PetVisualizationData.ts new file mode 100644 index 00000000..100fe79a --- /dev/null +++ b/src/nitro/room/object/visualization/pet/PetVisualizationData.ts @@ -0,0 +1,127 @@ +import { IAssetVisualizationData } from '../../../../../core/asset/interfaces'; +import { AnimationSizeData } from '../data/AnimationSizeData'; +import { PetSizeData } from '../data/PetSizeData'; +import { SizeData } from '../data/SizeData'; +import { FurnitureAnimatedVisualizationData } from '../furniture/FurnitureAnimatedVisualizationData'; + +export class PetVisualizationData extends FurnitureAnimatedVisualizationData +{ + private _isAllowedToTurnHead: boolean; + + constructor() + { + super(); + + this._isAllowedToTurnHead = true; + } + + protected createSizeData(scale: number, layerCount: number, angle: number): SizeData + { + if(scale > 1) return new PetSizeData(layerCount, angle); + else return new AnimationSizeData(layerCount, angle); + } + + protected defineVisualizations(visualizations: IAssetVisualizationData[]): boolean + { + this._isAllowedToTurnHead = true; //check visualization for '@disableheadturn' + + return super.defineVisualizations(visualizations); + } + + protected processVisualElement(sizeData: SizeData, key: string, data: any): boolean + { + if(!sizeData || !key || !data) return false; + + switch(key) + { + case 'postures': + if(!(sizeData instanceof PetSizeData) || !sizeData.processPostures(data)) return false; + break; + case 'gestures': + if(!(sizeData instanceof PetSizeData) || !sizeData.processGestures(data)) return false; + break; + default: + if(!super.processVisualElement(sizeData, key, data)) return false; + break; + } + + return true; + } + + public postureToAnimation(scale: number, posture: string): number + { + const size = this.getSizeData(scale) as PetSizeData; + + if(!size) return PetSizeData.DEFAULT; + + return size.postureToAnimation(posture); + } + + public _Str_18284(scale: number, posture: string): boolean + { + const size = this.getSizeData(scale) as PetSizeData; + + if(!size) return false; + + return size._Str_18284(posture); + } + + public gestureToAnimation(scale: number, gesture: string): number + { + const size = this.getSizeData(scale) as PetSizeData; + + if(!size) return PetSizeData.DEFAULT; + + return size.gestureToAnimation(gesture); + } + + public _Str_14207(scale: number, index: number, useDefault: boolean): string + { + const size = this.getSizeData(scale) as PetSizeData; + + if(!size) return null; + + return size._Str_14207(index, useDefault); + } + + public _Str_17844(scale: number, index: number): string + { + const size = this.getSizeData(scale) as PetSizeData; + + if(!size) return null; + + return size._Str_17844(index); + } + + public _Str_17976(scale: number, _arg_2: number): string + { + const size = this.getSizeData(scale) as PetSizeData; + + if(!size) return null; + + return size._Str_17976(_arg_2); + } + + public totalPostures(scale: number): number + { + const size = this.getSizeData(scale) as PetSizeData; + + if(!size) return 0; + + return size.totalPostures; + } + + public totalGestures(scale: number): number + { + const size = this.getSizeData(scale) as PetSizeData; + + if(!size) return 0; + + return size.totalGestures; + } + + public get isAllowedToTurnHead(): boolean + { + return this._isAllowedToTurnHead; + } +} diff --git a/src/nitro/room/object/visualization/room/PlaneDrawingData.ts b/src/nitro/room/object/visualization/room/PlaneDrawingData.ts new file mode 100644 index 00000000..a5c48b29 --- /dev/null +++ b/src/nitro/room/object/visualization/room/PlaneDrawingData.ts @@ -0,0 +1,103 @@ +import { Point } from 'pixi.js'; +import { IPlaneDrawingData } from '../../../../../room/object/visualization/IPlaneDrawingData'; + +export class PlaneDrawingData implements IPlaneDrawingData +{ + private _z: number; + private _points: Point[]; + private _color: number; + private _maskAssetNames: string[]; + private _maskAssetLocations: Point[]; + private _maskAssetFlipHs: boolean[]; + private _maskAssetFlipVs: boolean[]; + private _alignBottom: boolean; + private _assetNames: string[][]; + + constructor(k: PlaneDrawingData = null, _arg_2: number = 0, _arg_3: boolean = false) + { + this._assetNames = []; + this._maskAssetNames = []; + this._maskAssetLocations = []; + this._maskAssetFlipHs = []; + this._maskAssetFlipVs = []; + + if(k != null) + { + this._maskAssetNames = k._maskAssetNames; + this._maskAssetLocations = k._maskAssetLocations; + this._maskAssetFlipHs = k._maskAssetFlipHs; + this._maskAssetFlipVs = k._maskAssetFlipVs; + } + + this._color = _arg_2; + this._alignBottom = _arg_3; + } + + public addMask(k: string, _arg_2: Point, _arg_3: boolean, _arg_4: boolean): void + { + this._maskAssetNames.push(k); + this._maskAssetLocations.push(_arg_2); + this._maskAssetFlipHs.push(_arg_3); + this._maskAssetFlipVs.push(_arg_4); + } + + public _Str_22862(k: string[]): void + { + this._assetNames.push(k); + } + + public set z(k: number) + { + this._z = k; + } + + public get z(): number + { + return this._z; + } + + public set cornerPoints(k: Point[]) + { + this._points = k; + } + + public get cornerPoints(): Point[] + { + return this._points; + } + + public get color(): number + { + return this._color; + } + + public get _Str_21807(): string[] + { + return this._maskAssetNames; + } + + public get _Str_20731(): Point[] + { + return this._maskAssetLocations; + } + + public get _Str_21810(): boolean[] + { + return this._maskAssetFlipHs; + } + + public get _Str_19044(): boolean[] + { + return this._maskAssetFlipVs; + } + + public _Str_14945(): boolean + { + return this._alignBottom; + } + + public get _Str_17636(): string[][] + { + return this._assetNames; + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/room/RoomPlane.ts b/src/nitro/room/object/visualization/room/RoomPlane.ts new file mode 100644 index 00000000..95e5626c --- /dev/null +++ b/src/nitro/room/object/visualization/room/RoomPlane.ts @@ -0,0 +1,1021 @@ +import { Graphics, Matrix, Point, Rectangle, RenderTexture, Texture } from 'pixi.js'; +import { IRoomPlane } from '../../../../../room/object/visualization/IRoomPlane'; +import { IRoomGeometry } from '../../../../../room/utils/IRoomGeometry'; +import { IVector3D } from '../../../../../room/utils/IVector3D'; +import { TextureUtils } from '../../../../../room/utils/TextureUtils'; +import { Vector3d } from '../../../../../room/utils/Vector3d'; +import { Nitro } from '../../../../Nitro'; +import { PlaneMaskManager } from './mask/PlaneMaskManager'; +import { PlaneDrawingData } from './PlaneDrawingData'; +import { PlaneVisualizationLayer } from './rasterizer/basic/PlaneVisualizationLayer'; +import { IPlaneRasterizer } from './rasterizer/IPlaneRasterizer'; +import { RoomPlaneBitmapMask } from './RoomPlaneBitmapMask'; +import { RoomPlaneRectangleMask } from './RoomPlaneRectangleMask'; +import { RoomVisualization } from './RoomVisualization'; +import { PlaneBitmapData } from './utils/PlaneBitmapData'; +import { Randomizer } from './utils/Randomizer'; + +export class RoomPlane implements IRoomPlane +{ + private static ZERO_POINT: Point = new Point(0, 0); + public static TYPE_UNDEFINED: number = 0; + public static TYPE_WALL: number = 1; + public static TYPE_FLOOR: number = 2; + public static TYPE_LANDSCAPE: number = 3; + private static _uniqueIdCounter: number = 1; + + private _disposed: boolean; + private _Str_16308: number; + private _Str_5221: Vector3d; + private _location: Vector3d; + private _Str_2920: Vector3d; + private _Str_2943: Vector3d; + private _normal: Vector3d; + private _Str_5886: Vector3d[]; + private _Str_3406: number; + private _type: number; + private _Str_3816: boolean; + private _Str_1049: Graphics; + private _Str_13946: boolean; + private _offset: Point; + private _relativeDepth: number; + private _color: number; + private _rasterizer: IPlaneRasterizer; + private _Str_4795: PlaneMaskManager = null; + private _Str_576: string; + private _uniqueId: number; + private _Str_20541: number; + private _Str_19707: number; + private _Str_21079: number; + private _Str_22024: number; + private _Str_2708: Map; + private _Str_5545: PlaneBitmapData; + private _Str_4542: boolean; + private _Str_4047: RoomPlaneBitmapMask[]; + private _Str_5088: RoomPlaneRectangleMask[]; + private _Str_4891: boolean; + private _Str_2730: Graphics; + private _Str_8341: RoomPlaneBitmapMask[]; + private _Str_14495: RoomPlaneRectangleMask[]; + private _Str_2820:Vector3d; + private _Str_2745:Vector3d; + private _Str_2639:Vector3d; + private _Str_2766:Vector3d; + private _Str_1720: number = 0; + private _height: number = 0; + private _Str_7367: boolean; + + constructor(k: IVector3D, _arg_2: IVector3D, _arg_3: IVector3D, _arg_4: IVector3D, _arg_5: number, _arg_6: boolean, _arg_7: IVector3D[], _arg_8: number, _arg_9: number=0, _arg_10: number=0, _arg_11: number=0, _arg_12: number=0) + { + this._Str_5886 = []; + this._Str_4047 = []; + this._Str_5088 = []; + this._Str_8341 = []; + this._Str_14495 = []; + this._Str_16308 = _arg_8; + this._Str_1049 = null; + this._Str_2730 = null; + this._Str_4891 = false; + this._Str_5545 = null; + this._Str_5221 = new Vector3d(); + this._Str_5221.assign(k); + this._location = new Vector3d(); + this._location.assign(_arg_2); + this._Str_2920 = new Vector3d(); + this._Str_2920.assign(_arg_3); + this._Str_2943 = new Vector3d(); + this._Str_2943.assign(_arg_4); + this._normal = Vector3d.crossProduct(this._Str_2920, this._Str_2943); + if(this._normal.length > 0) + { + this._normal.multiply((1 / this._normal.length)); + } + if(_arg_7 != null) + { + for(const entry of _arg_7) + { + if(!entry) continue; + + const vector = new Vector3d(); + + vector.assign(entry); + + this._Str_5886.push(vector); + } + } + this._disposed = false; + this._Str_3816 = false; + this._Str_576 = null; + this._Str_13946 = true; + this._Str_3406 = -1; + this._offset = new Point(); + this._relativeDepth = 0; + this._type = _arg_5; + this._color = 0; + this._rasterizer = null; + this._Str_7367 = true; + this._Str_2708 = new Map(); + this._Str_2820 = new Vector3d(); + this._Str_2745 = new Vector3d(); + this._Str_2639 = new Vector3d(); + this._Str_2766 = new Vector3d(); + this._Str_1720 = 0; + this._height = 0; + this._Str_20541 = _arg_9; + this._Str_19707 = _arg_10; + this._Str_21079 = _arg_11; + this._Str_22024 = _arg_12; + this._Str_4542 = _arg_6; + this._uniqueId = ++RoomPlane._uniqueIdCounter; + } + + private static blend(k: number, _arg_2: number): number + { + return 0; + //return Canvas.colorize(_arg_2, (k | 0xFF000000)) & 0xFFFFFF; + } + + public set _Str_14801(k: boolean) + { + if(k !== this._Str_7367) + { + if(!this._Str_7367) this._Str_11000(); + + this._Str_7367 = k; + } + } + + public get _Str_14801(): boolean + { + return this._Str_7367; + } + + public get bitmapData(): Texture + { + if(!this.visible || !this._Str_1049) return null; + + let texture: RenderTexture = RoomVisualization.getTextureCache(this._Str_1049); + + if(!texture) + { + texture = TextureUtils.generateTexture(this._Str_1049, new Rectangle(0, 0, this._Str_1720, this._height)); + + RoomVisualization.addTextureCache(this._Str_1049, texture); + } + + return texture; + } + + public get visible(): boolean + { + return (this._Str_3816 && this._Str_7367); + } + + public get offset(): Point + { + return this._offset; + } + + public get relativeDepth(): number + { + return this._relativeDepth; + } + + public get color(): number + { + return this._color; + } + + public set color(k: number) + { + this._color = k; + } + + public get type(): number + { + return this._type; + } + + public get _Str_5424(): IVector3D + { + return this._Str_2920; + } + + public get _Str_4968(): IVector3D + { + return this._Str_2943; + } + + public get location(): IVector3D + { + return this._location; + } + + public get normal(): IVector3D + { + return this._normal; + } + + public get _Str_18448(): boolean + { + return this._Str_13946; + } + + public set _Str_18448(k: boolean) + { + this._Str_13946 = k; + } + + public set rasterizer(k:IPlaneRasterizer) + { + this._rasterizer = k; + } + + public set _Str_16279(k: PlaneMaskManager) + { + this._Str_4795 = k; + } + + public set id(k: string) + { + if(k === this._Str_576) return; + + this._Str_11000(); + this._Str_576 = k; + } + + public get uniqueId(): number + { + return this._uniqueId; + } + + public dispose(): void + { + if(this._Str_1049) + { + this._Str_1049.destroy(); + + this._Str_1049 = null; + } + + if(this._Str_2708) + { + for(const bitmap of this._Str_2708.values()) + { + if(!bitmap) continue; + + if(bitmap.bitmap) bitmap.bitmap.destroy(); + + bitmap.dispose(); + } + + this._Str_2708 = null; + } + + this._Str_5545 = null; + this._location = null; + this._Str_5221 = null; + this._Str_2920 = null; + this._Str_2943 = null; + this._normal = null; + this._rasterizer = null; + this._Str_2820 = null; + this._Str_2745 = null; + this._Str_2639 = null; + this._Str_2766 = null; + this._Str_4047 = null; + this._Str_5088 = null; + + if(this._Str_2730) + { + this._Str_2730.destroy(); + + this._Str_2730 = null; + } + + this._disposed = true; + } + + public _Str_24896(k: Texture): Texture + { + if(!this.visible || !this._Str_1049 || !k) return null; + + if((this._Str_1049.width !== k.width) || (this._Str_1049.height !== k.height)) return null; + + //k.copyPixels(this._Str_1049, this._Str_1049.rect, RoomPlane.ZERO_POINT); + return k; + } + + private _Str_17642(k: string, _arg_2: PlaneBitmapData): boolean + { + const existing = this._Str_2708.get(k); + + if(existing) + { + this._Str_2708.delete(k); + + existing.dispose(); + } + + this._Str_5545 = _arg_2; + this._Str_2708.set(k, _arg_2); + + return true; + } + + private _Str_11000(k: Graphics = null): void + { + if(this._Str_2708 && this._Str_2708.size) + { + for(const bitmap of this._Str_2708.values()) + { + if(!bitmap) continue; + + bitmap.dispose(); + } + + this._Str_2708.clear(); + } + + this._Str_5545 = null; + } + + private getTextureIdentifier(k: number): string + { + if(this._rasterizer) return this._rasterizer.getTextureIdentifier(k, this.normal); + + return k.toString(); + } + + private _Str_10518(k: IRoomGeometry, _arg_2: number): boolean + { + if(!k) return false; + + let planeBitmap = this._Str_5545; + + if(!planeBitmap) + { + planeBitmap = this._Str_2708.get(this.getTextureIdentifier(k.scale)); + } + + this._Str_19336(); + + if(this._Str_7367 && ((!planeBitmap || ((planeBitmap.timeStamp >= 0) && (_arg_2 > planeBitmap.timeStamp))) || this._Str_4891)) return true; + + return false; + } + + private _Str_10114(k: IRoomGeometry, _arg_2: number): Graphics + { + if(!k) return null; + + let _local_3: PlaneBitmapData = null; + + if(this._Str_10518(k, _arg_2)) + { + const _local_4 = this.getTextureIdentifier(k.scale); + const _local_5 = (this._Str_2920.length * k.scale); + const _local_6 = (this._Str_2943.length * k.scale); + const _local_7 = k.getCoordinatePosition(this._normal); + + if(this._Str_5545) + { + _local_3 = this._Str_5545; + } + else + { + _local_3 = this._Str_2708.get(_local_4); + } + + let _local_8: Graphics = null; + + if(_local_3) _local_8 = _local_3.bitmap; + + if(this._rasterizer) + { + _local_3 = this._rasterizer.render(_local_8, this._Str_576, _local_5, _local_6, k.scale, _local_7, this._Str_13946, this._Str_20541, this._Str_19707, this._Str_21079, this._Str_22024, _arg_2); + + if(_local_3) + { + if(_local_8 && (_local_3.bitmap !== _local_8)) _local_8.destroy(); + } + } + else + { + const _local_9 = new Graphics(); + + _local_9.beginFill(0xFFFFFF); + _local_9.drawRect(0, 0, _local_5, _local_6); + _local_9.endFill(); + + _local_3 = new PlaneBitmapData(_local_9, -1); + } + + if(_local_3) + { + this._Str_17859(_local_3.bitmap, k); + this._Str_17642(_local_4, _local_3); + } + } + else + { + if(this._Str_5545) + { + _local_3 = this._Str_5545; + } + else + { + _local_3 = this._Str_2708.get(this.getTextureIdentifier(k.scale)); + } + } + + if(_local_3) + { + this._Str_5545 = _local_3; + + return _local_3.bitmap; + } + + return null; + } + + private _Str_23649(k: IRoomGeometry): PlaneDrawingData + { + if(!this._Str_4542) return null; + + const _local_5 = new PlaneDrawingData(); + + const index = 0; + + while(index < this._Str_4047.length) + { + const mask = this._Str_4047[index]; + + if(mask) + { + const planeMask = this._Str_4795._Str_8361(mask.type); + + if(planeMask) + { + const assetName = planeMask._Str_2125(k.scale); + + if(assetName) + { + const position = k.getCoordinatePosition(this._normal); + const asset = planeMask._Str_21021(k.scale, position); + + if(asset) + { + const _local_3 = (this._Str_2730.width * (1 - (mask._Str_5120 / this._Str_2920.length))); + const _local_4 = (this._Str_2730.height * (1 - (mask._Str_4659 / this._Str_2943.length))); + const _local_11 = new Point((_local_3 + asset.offsetX), (_local_4 + asset.offsetY)); + + _local_5.addMask(assetName, _local_11, asset.flipH, asset.flipV); + } + } + } + } + } + + return _local_5; + } + + private _Str_24802(k: IRoomGeometry): number + { + const _local_2 = k.getScreenPoint(new Vector3d(0, 0, 0)); + const _local_3 = k.getScreenPoint(new Vector3d(0, 1, 0)); + + return Math.round((this._Str_2920.length * Math.abs((_local_2.x - _local_3.x)))); + } + + public _Str_22136(geometry:IRoomGeometry): PlaneDrawingData[] + { + const drawingDatas: PlaneDrawingData[] = []; + + if(this._Str_3816) + { + const maskData = this._Str_23649(geometry); + const layers = this._rasterizer._Str_8988(this._Str_576); + + let i = 0; + + while(i < layers.length) + { + const layer = (layers[i] as PlaneVisualizationLayer); + + if(layer) + { + if(this._Str_13946 && layer._Str_8547()) + { + const normal = geometry.getCoordinatePosition(this._normal); + const cm = layer._Str_8547()._Str_21968(normal); + //const data = new PlaneDrawingData(maskData, blend(this._color, layer._Str_751()), cm._Str_14945()); + const data = new PlaneDrawingData(maskData, this._color, cm._Str_14945()); + + Randomizer._Str_17384(this._Str_16308); + + for(const column of cm._Str_23721(this._Str_24802(geometry))) + { + const assetNames: string[] = []; + + for(const cell of column._Str_22299()) + { + const name = cell._Str_2125(normal); + + if(name) assetNames.push(name); + } + + if(assetNames.length > 0) + { + if(!column._Str_24523()) assetNames.push(''); + + data._Str_22862(assetNames); + } + } + + if(data._Str_17636.length > 0) drawingDatas.push(data); + } + else + { + //data = new PlaneDrawingData(maskData, blend(this._color, layer._Str_751())); + const data = new PlaneDrawingData(maskData, this._color); + + drawingDatas.push(data); + } + } + + i++; + } + + if(!drawingDatas.length) drawingDatas.push(new PlaneDrawingData(maskData, this._color)); + } + + return drawingDatas; + } + + // private _Str_25956(k:PlaneBitmapData): void + // { + // } + + public update(geometry: IRoomGeometry, timeSinceStartMs: number): boolean + { + if(!geometry || this._disposed) return false; + + let geometryChanged = false; + + if(this._Str_3406 != geometry.updateId) geometryChanged = true; + + if(!geometryChanged || !this._Str_7367) + { + if(!this.visible) return false; + } + + if(geometryChanged) + { + this._Str_5545 = null; + + let cosAngle = 0; + + cosAngle = Vector3d.cosAngle(geometry.directionAxis, this.normal); + + if(cosAngle > -0.001) + { + if(this._Str_3816) + { + this._Str_3816 = false; + return true; + } + + return false; + } + + let i = 0; + + while(i < this._Str_5886.length) + { + cosAngle = Vector3d.cosAngle(geometry.directionAxis, this._Str_5886[i]); + + if(cosAngle > -0.001) + { + if(this._Str_3816) + { + this._Str_3816 = false; + return true; + } + + return false; + } + + i++; + } + + this._Str_18702(geometry); + + const originPos = geometry.getScreenPosition(this._Str_5221); + const originZ = originPos.z; + + let relativeDepth = (Math.max(this._Str_2820.z, this._Str_2745.z, this._Str_2639.z, this._Str_2766.z) - originZ); + + if(this._type === RoomPlane.TYPE_FLOOR) + { + relativeDepth = (relativeDepth - ((this._location.z + Math.min(0, this._Str_2920.z, this._Str_2943.z)) * 8)); + } + + if(this._type === RoomPlane.TYPE_LANDSCAPE) + { + relativeDepth = (relativeDepth + 0.02); + } + + this._relativeDepth = relativeDepth; + this._Str_3816 = true; + this._Str_3406 = geometry.updateId; + } + + if(geometryChanged || this._Str_10518(geometry, timeSinceStartMs)) + { + if(!this._Str_1049 || (this._Str_1720 !== this._Str_1049.width) || (this._height !== this._Str_1049.height)) + { + if(this._Str_1049) + { + this._Str_1049.destroy(); + + this._Str_1049 = null; + + if((this._Str_1720 < 1) || (this._height < 1)) return true; + } + else + { + if((this._Str_1720 < 1) || (this._height < 1)) return false; + } + + const graphic = new Graphics(); + + graphic.beginFill(0xFFFFFF, 0); + graphic.drawRect(0, 0, this._Str_1720, this._height); + graphic.endFill(); + + this._Str_1049 = graphic; + + if(!this._Str_1049) return false; + } + else + { + //this._Str_1049.lock(); + //this._Str_1049.fillRect(this._Str_1049.rect, 0xFFFFFF); + } + + Randomizer._Str_17384(this._Str_16308); + + const texture = this._Str_10114(geometry, timeSinceStartMs); + + if(texture) + { + this._Str_17000(geometry, texture); + } + else + { + this.dispose(); + + return false; + } + + return ((texture !== null) || geometryChanged); + } + + return false; + } + + private _Str_18702(k: IRoomGeometry): void + { + this._Str_2820.assign(k.getScreenPosition(this._location)); + this._Str_2745.assign(k.getScreenPosition(Vector3d.sum(this._location, this._Str_2943))); + this._Str_2639.assign(k.getScreenPosition(Vector3d.sum(Vector3d.sum(this._location, this._Str_2920), this._Str_2943))); + this._Str_2766.assign(k.getScreenPosition(Vector3d.sum(this._location, this._Str_2920))); + this._offset = k.getScreenPoint(this._Str_5221); + this._Str_2820.x = Math.round(this._Str_2820.x); + this._Str_2820.y = Math.round(this._Str_2820.y); + this._Str_2745.x = Math.round(this._Str_2745.x); + this._Str_2745.y = Math.round(this._Str_2745.y); + this._Str_2639.x = Math.round(this._Str_2639.x); + this._Str_2639.y = Math.round(this._Str_2639.y); + this._Str_2766.x = Math.round(this._Str_2766.x); + this._Str_2766.y = Math.round(this._Str_2766.y); + this._offset.x = Math.round(this._offset.x); + this._offset.y = Math.round(this._offset.y); + const _local_2: number = Math.min(this._Str_2820.x, this._Str_2745.x, this._Str_2639.x, this._Str_2766.x); + let _local_3: number = Math.max(this._Str_2820.x, this._Str_2745.x, this._Str_2639.x, this._Str_2766.x); + const _local_4: number = Math.min(this._Str_2820.y, this._Str_2745.y, this._Str_2639.y, this._Str_2766.y); + let _local_5: number = Math.max(this._Str_2820.y, this._Str_2745.y, this._Str_2639.y, this._Str_2766.y); + _local_3 = (_local_3 - _local_2); + this._offset.x = (this._offset.x - _local_2); + this._Str_2820.x = (this._Str_2820.x - _local_2); + this._Str_2745.x = (this._Str_2745.x - _local_2); + this._Str_2639.x = (this._Str_2639.x - _local_2); + this._Str_2766.x = (this._Str_2766.x - _local_2); + _local_5 = (_local_5 - _local_4); + this._offset.y = (this._offset.y - _local_4); + this._Str_2820.y = (this._Str_2820.y - _local_4); + this._Str_2745.y = (this._Str_2745.y - _local_4); + this._Str_2639.y = (this._Str_2639.y - _local_4); + this._Str_2766.y = (this._Str_2766.y - _local_4); + this._Str_1720 = _local_3; + this._height = _local_5; + } + + private _Str_17000(k: IRoomGeometry, _arg_2: Graphics): void + { + if(((((((this._Str_2820 == null) || (this._Str_2745 == null)) || (this._Str_2639 == null)) || (this._Str_2766 == null)) || (_arg_2 == null)) || (this._Str_1049 == null))) + { + return; + } + let _local_3: number = (this._Str_2766.x - this._Str_2639.x); + let _local_4: number = (this._Str_2766.y - this._Str_2639.y); + let _local_5: number = (this._Str_2745.x - this._Str_2639.x); + let _local_6: number = (this._Str_2745.y - this._Str_2639.y); + if(((this._type == RoomPlane.TYPE_WALL) || (this._type == RoomPlane.TYPE_LANDSCAPE))) + { + if(Math.abs((_local_5 - _arg_2.width)) <= 1) + { + _local_5 = _arg_2.width; + } + if(Math.abs((_local_6 - _arg_2.width)) <= 1) + { + _local_6 = _arg_2.width; + } + if(Math.abs((_local_3 - _arg_2.height)) <= 1) + { + _local_3 = _arg_2.height; + } + if(Math.abs((_local_4 - _arg_2.height)) <= 1) + { + _local_4 = _arg_2.height; + } + } + const _local_7: number = (_local_5 / _arg_2.width); + const _local_8: number = (_local_6 / _arg_2.width); + const _local_9: number = (_local_3 / _arg_2.height); + const _local_10: number = (_local_4 / _arg_2.height); + const _local_11 = new Matrix(); + _local_11.a = _local_7; + _local_11.b = _local_8; + _local_11.c = _local_9; + _local_11.d = _local_10; + _local_11.translate(this._Str_2639.x, this._Str_2639.y); + + this.draw(_arg_2, _local_11); + } + + private draw(k: Graphics, matrix: Matrix): void + { + const clone = k.clone(); + + clone.transform.setFromMatrix(matrix); + + this._Str_1049 = clone; + } + + public _Str_25213(): void + { + if(this._disposed || !this._Str_4542 || !this._Str_4047.length) return; + + this._Str_4891 = true; + this._Str_4047 = []; + } + + public _Str_24569(k: string, _arg_2: number, _arg_3: number): boolean + { + if(!this._Str_4542) return false; + + let _local_5 = 0; + + while(_local_5 < this._Str_4047.length) + { + const mask = this._Str_4047[_local_5]; + + if(mask) + { + if((((mask.type === k) && (mask._Str_5120 === _arg_2)) && (mask._Str_4659 === _arg_3))) return false; + } + + _local_5++; + } + + const mask = new RoomPlaneBitmapMask(k, _arg_2, _arg_3); + + this._Str_4047.push(mask); + this._Str_4891 = true; + + return true; + } + + public _Str_25934(): void + { + if(!this._Str_4542 || !this._Str_5088.length) return; + + this._Str_4891 = true; + this._Str_5088 = []; + } + + public _Str_24758(k: number, _arg_2: number, _arg_3: number, _arg_4: number): boolean + { + if(this._Str_4542) + { + for(const mask of this._Str_5088) + { + if(!mask) continue; + + if((((mask._Str_5120 === k) && (mask._Str_4659 === _arg_2)) && (mask._Str_9124 === _arg_3)) && (mask._Str_12156 === _arg_4)) return false; + } + + const _local_5 = new RoomPlaneRectangleMask(k, _arg_2, _arg_3, _arg_4); + + this._Str_5088.push(_local_5); + this._Str_4891 = true; + + return true; + } + + return false; + } + + private _Str_19336(): void + { + if(!this._Str_4891) return; + + let _local_3 = true; + let _local_6: boolean; + + if(this._Str_4047.length === this._Str_8341.length) + { + for(const mask of this._Str_4047) + { + if(!mask) continue; + + _local_6 = false; + + for(const plane of this._Str_8341) + { + if(!plane) continue; + + if(((plane.type === mask.type) && (plane._Str_5120 === mask._Str_5120)) && (plane._Str_4659 === mask._Str_4659)) + { + _local_6 = true; + + break; + } + } + + if(!_local_6) + { + _local_3 = false; + + break; + } + } + } + else + { + _local_3 = false; + } + + if(this._Str_5088.length > this._Str_14495.length) _local_3 = false; + + if(_local_3) this._Str_4891 = false; + } + + private _Str_17859(texture: Graphics, geometry: IRoomGeometry): void + { + if(!texture || !geometry) return; + + if(((!this._Str_4542) || ((!this._Str_4047.length && !this._Str_5088.length) && !this._Str_4891)) || !this._Str_4795) return; + + const width = texture.width; + const height = texture.height; + + this._Str_19336(); + + if(!this._Str_2730 || (this._Str_2730.width !== width) || (this._Str_2730.height !== height)) + { + if(this._Str_2730) + { + this._Str_2730.destroy(); + this._Str_2730 = null; + } + + const graphic = new Graphics(); + + graphic + .beginFill(0xFFFFFF, 0) + .drawRect(0, 0, width, height) + .endFill(); + + this._Str_2730 = graphic; + this._Str_4891 = true; + } + + if(this._Str_4891) + { + this._Str_8341 = []; + this._Str_14495 = []; + + if(this._Str_2730) + { + this._Str_2730 + .beginFill(0xFFFFFF, 0) + .drawRect(0, 0, width, height) + .endFill(); + } + + this._Str_11000(texture); + + const normal = geometry.getCoordinatePosition(this._normal); + + let type: string = null; + let posX = 0; + let posY = 0; + let i = 0; + + while(i < this._Str_4047.length) + { + const mask = this._Str_4047[i]; + + if(mask) + { + type = mask.type; + posX = (this._Str_2730.width - ((this._Str_2730.width * mask._Str_5120) / this._Str_2920.length)); + posY = (this._Str_2730.height - ((this._Str_2730.height * mask._Str_4659) / this._Str_2943.length)); + + this._Str_4795._Str_17859(this._Str_2730, type, geometry.scale, normal, posX, posY); + this._Str_8341.push(new RoomPlaneBitmapMask(type, mask._Str_5120, mask._Str_4659)); + } + + i++; + } + + i = 0; + + while(i < this._Str_5088.length) + { + const rectMask = this._Str_5088[i]; + + if(rectMask) + { + posX = (this._Str_2730.width - ((this._Str_2730.width * rectMask._Str_5120) / this._Str_2920.length)); + posY = (this._Str_2730.height - ((this._Str_2730.height * rectMask._Str_4659) / this._Str_2943.length)); + + const wd = ((this._Str_2730.width * rectMask._Str_9124) / this._Str_2920.length); + const ht = ((this._Str_2730.height * rectMask._Str_12156) / this._Str_2943.length); + + this._Str_2730 + .beginFill(0xFF0000) + .drawRect((posX - wd), (posY - ht), wd, ht) + .endFill(); + + this._Str_14495.push(new RoomPlaneRectangleMask(rectMask._Str_9124, rectMask._Str_4659, rectMask._Str_9124, rectMask._Str_12156)); + } + + i++; + } + + this._Str_4891 = false; + } + + this._Str_24790(texture, this._Str_2730); + } + + private _Str_24790(texture: Graphics, mask: Graphics): void + { + if(!texture || !mask) return; + + const maskCanvas = Nitro.instance.renderer.extract.canvas(mask); + const textureCanvas = Nitro.instance.renderer.extract.canvas(texture); + const textureCtx = textureCanvas.getContext('2d'); + + textureCtx.drawImage(maskCanvas, 0, 0); + + const textureImageData = textureCtx.getImageData(0, 0, textureCanvas.width, textureCanvas.height); + const data = textureImageData.data; + + for(let i = 0; i < data.length; i += 4) + { + const red = data[ i ]; + const green = data[ i + 1 ]; + const blue = data[ i + 2 ]; + const alpha = data[ i + 3 ]; + + if(!red && !green && !blue) data[ i + 3 ] = 0; + } + + textureCtx.putImageData(textureImageData, 0, 0); + + const newTexture = Texture.from(textureCanvas); + + if(!newTexture) return; + + texture + .clear() + .beginTextureFill({ texture: newTexture }) + .drawRect(0, 0, newTexture.width, newTexture.height) + .endFill(); + } +} diff --git a/src/nitro/room/object/visualization/room/RoomPlaneBitmapMask.ts b/src/nitro/room/object/visualization/room/RoomPlaneBitmapMask.ts new file mode 100644 index 00000000..1d12b7d9 --- /dev/null +++ b/src/nitro/room/object/visualization/room/RoomPlaneBitmapMask.ts @@ -0,0 +1,28 @@ +export class RoomPlaneBitmapMask +{ + private _type: string; + private _leftSideLoc: number; + private _rightSideLoc: number; + + constructor(k: string, _arg_2: number, _arg_3: number) + { + this._type = k; + this._leftSideLoc = _arg_2; + this._rightSideLoc = _arg_3; + } + + public get type(): string + { + return this._type; + } + + public get _Str_5120(): number + { + return this._leftSideLoc; + } + + public get _Str_4659(): number + { + return this._rightSideLoc; + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/room/RoomPlaneRectangleMask.ts b/src/nitro/room/object/visualization/room/RoomPlaneRectangleMask.ts new file mode 100644 index 00000000..b36a9feb --- /dev/null +++ b/src/nitro/room/object/visualization/room/RoomPlaneRectangleMask.ts @@ -0,0 +1,35 @@ +export class RoomPlaneRectangleMask +{ + private _leftSideLoc: number; + private _rightSideLoc: number; + private _leftSideLength: number; + private _rightSideLength: number; + + constructor(k: number, _arg_2: number, _arg_3: number, _arg_4: number) + { + this._leftSideLoc = k; + this._rightSideLoc = _arg_2; + this._leftSideLength = _arg_3; + this._rightSideLength = _arg_4; + } + + public get _Str_5120(): number + { + return this._leftSideLoc; + } + + public get _Str_4659(): number + { + return this._rightSideLoc; + } + + public get _Str_9124(): number + { + return this._leftSideLength; + } + + public get _Str_12156(): number + { + return this._rightSideLength; + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/room/RoomVisualization.ts b/src/nitro/room/object/visualization/room/RoomVisualization.ts new file mode 100644 index 00000000..988467d1 --- /dev/null +++ b/src/nitro/room/object/visualization/room/RoomVisualization.ts @@ -0,0 +1,1015 @@ +import { Rectangle, RenderTexture, Texture } from 'pixi.js'; +import { AdvancedMap } from '../../../../../core/utils/AdvancedMap'; +import { AlphaTolerance } from '../../../../../room/object/enum/AlphaTolerance'; +import { RoomObjectSpriteType } from '../../../../../room/object/enum/RoomObjectSpriteType'; +import { IRoomObjectModel } from '../../../../../room/object/IRoomObjectModel'; +import { IPlaneVisualization } from '../../../../../room/object/visualization/IPlaneVisualization'; +import { IRoomObjectSprite } from '../../../../../room/object/visualization/IRoomObjectSprite'; +import { IObjectVisualizationData } from '../../../../../room/object/visualization/IRoomObjectVisualizationData'; +import { IRoomPlane } from '../../../../../room/object/visualization/IRoomPlane'; +import { RoomObjectSpriteVisualization } from '../../../../../room/object/visualization/RoomObjectSpriteVisualization'; +import { IRoomGeometry } from '../../../../../room/utils/IRoomGeometry'; +import { Vector3d } from '../../../../../room/utils/Vector3d'; +import { RoomMapData } from '../../RoomMapData'; +import { RoomMapMaskData } from '../../RoomMapMaskData'; +import { RoomObjectVariable } from '../../RoomObjectVariable'; +import { RoomPlaneBitmapMaskData } from '../../RoomPlaneBitmapMaskData'; +import { RoomPlaneBitmapMaskParser } from '../../RoomPlaneBitmapMaskParser'; +import { RoomPlaneData } from '../../RoomPlaneData'; +import { RoomPlaneParser } from '../../RoomPlaneParser'; +import { RoomPlane } from './RoomPlane'; +import { RoomVisualizationData } from './RoomVisualizationData'; + +export class RoomVisualization extends RoomObjectSpriteVisualization implements IPlaneVisualization +{ + public static LAST_VISUALIZATION: RoomVisualization = null; + + public static RENDER_TEXTURE_CACHE: Map> = new Map(); + + public static _Str_18544: number = 0xFFFFFF; + public static _Str_18640: number = 0xDDDDDD; + public static _Str_16664: number = 0xBBBBBB; + private static _Str_14503: number = 0xFFFFFF; + private static _Str_15851: number = 0xCCCCCC; + private static _Str_13715: number = 0x999999; + private static _Str_14868: number = 0x999999; + public static _Str_17403: number = 0xFFFFFF; + public static _Str_16113: number = 0xCCCCCC; + public static _Str_18370: number = 0x999999; + private static _Str_8621: number = 1000; + + protected _data: RoomVisualizationData; + + private _roomPlaneParser: RoomPlaneParser; + private _roomPlaneBitmapMaskParser: RoomPlaneBitmapMaskParser; + + private _geometryUpdateId: number; + private _boundingRectangle: Rectangle; + private _directionX: number; + private _directionY: number; + private _directionZ: number; + private _floorThickness: number; + private _wallThickness: number; + private _holeUpdateTime: number; + private _Str_2540: RoomPlane[]; + private _Str_4864: RoomPlane[]; + private _Str_6648: number[]; + private _roomScale: number; + private _lastUpdateTime: number; + private _updateIntervalTime: number; + private _wallType: string; + private _floorType: string; + private _landscapeType: string; + private _colorBackgroundOnly: boolean; + private _color: number; + private _redColor: number; + private _greenColor: number; + private _blueColor: number; + private _typeVisibility: boolean[]; + private _Str_5928: number; + private _maskData: RoomMapMaskData; + private _isPlaneSet: boolean; + + constructor() + { + super(); + + this._data = null; + + this._roomPlaneParser = new RoomPlaneParser(); + this._roomPlaneBitmapMaskParser = new RoomPlaneBitmapMaskParser(); + + this._geometryUpdateId = -1; + this._directionX = 0; + this._directionY = 0; + this._directionZ = 0; + this._floorThickness = 1; + this._wallThickness = 1; + this._holeUpdateTime = NaN; + this._Str_2540 = []; + this._Str_4864 = []; + this._Str_6648 = []; + this._roomScale = 0; + this._lastUpdateTime = -1000; + this._updateIntervalTime = 250; + this._wallType = null; + this._floorType = null; + this._landscapeType = null; + this._colorBackgroundOnly = true; + this._color = 0xFFFFFF; + this._redColor = 0xFF; + this._greenColor = 0xFF; + this._blueColor = 0xFF; + this._typeVisibility = []; + this._Str_5928 = 0; + this._maskData = null; + this._isPlaneSet = false; + + this._typeVisibility[RoomPlane.TYPE_UNDEFINED] = false; + this._typeVisibility[RoomPlane.TYPE_FLOOR] = true; + this._typeVisibility[RoomPlane.TYPE_WALL] = true; + this._typeVisibility[RoomPlane.TYPE_LANDSCAPE] = true; + } + + public static getTextureCache(key: any): RenderTexture + { + const existing = RoomVisualization.RENDER_TEXTURE_CACHE.get(RoomVisualization.LAST_VISUALIZATION); + + if(!existing) return null; + + return existing.getValue(key); + } + + public static addTextureCache(key: any, value: RenderTexture): void + { + if(!RoomVisualization.LAST_VISUALIZATION) return; + + let existing = RoomVisualization.RENDER_TEXTURE_CACHE.get(RoomVisualization.LAST_VISUALIZATION); + + if(!existing) + { + existing = new AdvancedMap(); + + RoomVisualization.RENDER_TEXTURE_CACHE.set(RoomVisualization.LAST_VISUALIZATION, existing); + } + + existing.add(key, value); + } + + public initialize(data: IObjectVisualizationData): boolean + { + if(!(data instanceof RoomVisualizationData)) return false; + + this._data = data; + + super.initialize(data); + + this._data.setGraphicAssetCollection(this.asset); + + return true; + } + + public dispose(): void + { + super.dispose(); + + this.clearPlanes(); + + this._Str_2540 = null; + this._Str_4864 = null; + this._Str_6648 = null; + + if(this._roomPlaneParser) + { + this._roomPlaneParser.dispose(); + + this._roomPlaneParser = null; + } + + if(this._roomPlaneBitmapMaskParser) + { + this._roomPlaneBitmapMaskParser.dispose(); + + this._roomPlaneBitmapMaskParser = null; + } + + if(this._data) + { + this._data._Str_3355(); + + this._data = null; + } + + const existingTextureCache = RoomVisualization.RENDER_TEXTURE_CACHE.get(this); + + if(existingTextureCache) + { + for(const texture of existingTextureCache.getValues()) + { + texture.destroy(true); + } + + existingTextureCache.dispose(); + + RoomVisualization.RENDER_TEXTURE_CACHE.delete(this); + } + } + + protected reset(): void + { + super.reset(); + + this._floorType = null; + this._wallType = null; + this._landscapeType = null; + this._maskData = null; + this._geometryUpdateId = -1; + this._roomScale = 0; + } + + public update(geometry: IRoomGeometry, time: number, update: boolean, skipUpdate: boolean): void + { + if(!this.object || !geometry) return; + + RoomVisualization.LAST_VISUALIZATION = this; + + let removeCount = 0; + + const existing = RoomVisualization.RENDER_TEXTURE_CACHE.get(RoomVisualization.LAST_VISUALIZATION); + + if(existing) removeCount = existing.length; + + const geometryUpdate = this.updateGeometry(geometry); + const objectModel = this.object.model; + + let needsUpdate = false; + + if(this.updateThickness(objectModel)) needsUpdate = true; + + if(this.updateHole(objectModel)) needsUpdate = true; + + if(this._Str_25732()) + { + if(existing && removeCount) + { + setTimeout(() => + { + while(removeCount) + { + const texture = existing.getWithIndex(0); + + if(texture) + { + texture.destroy(true); + + existing.remove(existing.getKey(0)); + } + + removeCount--; + } + }, 0); + } + } + + needsUpdate = this.updateMasks(objectModel); + + if(((time < (this._lastUpdateTime + this._updateIntervalTime)) && (!geometryUpdate)) && (!needsUpdate)) return; + + if(this.updatePlanes(objectModel)) needsUpdate = true; + + if(this._Str_16913(geometry, geometryUpdate, time)) needsUpdate = true; + + if(needsUpdate) + { + let index = 0; + + while(index < this._Str_4864.length) + { + const spriteIndex = this._Str_6648[index]; + const sprite = this.getSprite(spriteIndex); + const plane = this._Str_4864[index]; + + if(sprite && plane && (plane.type !== RoomPlane.TYPE_LANDSCAPE)) + { + if(this._colorBackgroundOnly) + { + let _local_14 = plane.color; + + const _local_15 = (((_local_14 & 0xFF) * this._redColor) / 0xFF); + const _local_16 = ((((_local_14 >> 8) & 0xFF) * this._greenColor) / 0xFF); + const _local_17 = ((((_local_14 >> 16) & 0xFF) * this._blueColor) / 0xFF); + const _local_18 = (_local_14 >> 24); + + _local_14 = ((((_local_18 << 24) + (_local_17 << 16)) + (_local_16 << 8)) + _local_15); + + sprite.color = _local_14; + } + else + { + sprite.color = plane.color; + } + } + + index++; + } + + this.updateSpriteCounter++; + } + + this.updateModelCounter = objectModel.updateCounter; + this._lastUpdateTime = time; + } + + private updateGeometry(k: IRoomGeometry): boolean + { + if(!k) return false; + + if(this._geometryUpdateId === k.updateId) return false; + + this._geometryUpdateId = k.updateId; + this._boundingRectangle = null; + + const direction = k.direction; + + if(direction && ((direction.x !== this._directionX) || (direction.y !== this._directionY) || (direction.z !== this._directionZ) || (k.scale !== this._roomScale))) + { + this._directionX = direction.x; + this._directionY = direction.y; + this._directionZ = direction.z; + this._roomScale = k.scale; + + return true; + } + + return false; + } + + private updateThickness(k: IRoomObjectModel): boolean + { + if(this.updateModelCounter === k.updateCounter) return false; + + const floorThickness = k.getValue(RoomObjectVariable.ROOM_FLOOR_THICKNESS); + const wallThickness = k.getValue(RoomObjectVariable.ROOM_WALL_THICKNESS); + + if((!isNaN(floorThickness) && !isNaN(wallThickness)) && ((floorThickness !== this._floorThickness) || (wallThickness !== this._wallThickness))) + { + this._floorThickness = floorThickness; + this._wallThickness = wallThickness; + + this.clearPlanes(); + + return true; + } + + return false; + } + + private updateHole(k: IRoomObjectModel): boolean + { + if(this.updateModelCounter === k.updateCounter) return false; + + const holeUpdate = k.getValue(RoomObjectVariable.ROOM_FLOOR_HOLE_UPDATE_TIME); + + if(!isNaN(holeUpdate) && (holeUpdate !== this._holeUpdateTime)) + { + this._holeUpdateTime = holeUpdate; + + this.clearPlanes(); + + return true; + } + + return false; + } + + private updateMasks(k: IRoomObjectModel): boolean + { + if(this.updateModelCounter === k.updateCounter) return false; + + let didUpdate = false; + + const planeMask = k.getValue(RoomObjectVariable.ROOM_PLANE_MASK_XML); + + if(planeMask !== this._maskData) + { + this._Str_15935(planeMask); + + this._maskData = planeMask; + + didUpdate = true; + } + + const backgroundColor = k.getValue(RoomObjectVariable.ROOM_BACKGROUND_COLOR); + + if(backgroundColor !== this._color) + { + this._color = backgroundColor; + this._redColor = (this._color & 0xFF); + this._greenColor = ((this._color >> 8) & 0xFF); + this._blueColor = ((this._color >> 16) & 0xFF); + + didUpdate = true; + } + + const backgroundOnly = (k.getValue(RoomObjectVariable.ROOM_COLORIZE_BG_ONLY) || false); + + if(backgroundOnly !== this._colorBackgroundOnly) + { + this._colorBackgroundOnly = backgroundOnly; + + didUpdate = true; + } + + return didUpdate; + } + + private updatePlanes(model: IRoomObjectModel): boolean + { + if(this.updateModelCounter === model.updateCounter) return false; + + const floorType = model.getValue(RoomObjectVariable.ROOM_FLOOR_TYPE); + const wallType = model.getValue(RoomObjectVariable.ROOM_WALL_TYPE); + const landscapeType = model.getValue(RoomObjectVariable.ROOM_LANDSCAPE_TYPE); + + this.updatePlaneTypes(floorType, wallType, landscapeType); + + const floorVisibility = (model.getValue(RoomObjectVariable.ROOM_FLOOR_VISIBILITY) === 1); + const wallVisibility = (model.getValue(RoomObjectVariable.ROOM_WALL_VISIBILITY) === 1); + const landscapeVisibility = (model.getValue(RoomObjectVariable.ROOM_LANDSCAPE_VISIBILITY) === 1); + + this.updatePlaneVisibility(floorVisibility, wallVisibility, landscapeVisibility); + + return true; + } + + private clearPlanes(): void + { + if(this._Str_2540) + { + while(this._Str_2540.length) + { + const plane = this._Str_2540[0]; + + if(plane) plane.dispose(); + + this._Str_2540.pop(); + } + + this._Str_2540 = []; + this._Str_2540 = []; + } + + this._isPlaneSet = false; + this._Str_5928 = (this._Str_5928 + 1); + + this.reset(); + } + + protected _Str_25732(): boolean + { + if(!this.object || this._isPlaneSet) return false; + + if(!isNaN(this._floorThickness)) this._roomPlaneParser.floorThicknessMultiplier = this._floorThickness; + if(!isNaN(this._wallThickness)) this._roomPlaneParser.wallThicknessMultiplier = this._wallThickness; + + const mapData = this.object.model.getValue(RoomObjectVariable.ROOM_MAP_DATA); + + if(!this._roomPlaneParser.initializeFromMapData(mapData)) return; + + const _local_3 = this._Str_23949(); + const _local_4 = this._Str_23063(); + + let _local_5 = 0; + let _local_6 = this.object.model.getValue(RoomObjectVariable.ROOM_RANDOM_SEED); + let index = 0; + + while(index < this._roomPlaneParser.planeCount) + { + const location = this._roomPlaneParser.getPlaneLocation(index); + const leftSide = this._roomPlaneParser.getPlaneLeftSide(index); + const rightSide = this._roomPlaneParser.getPlaneRightSide(index); + const secondaryNormals = this._roomPlaneParser.getPlaneSecondaryNormals(index); + const planeType = this._roomPlaneParser.getPlaneType(index); + + let plane: RoomPlane = null; + + if(location && leftSide && rightSide) + { + const _local_14 = Vector3d.crossProduct(leftSide, rightSide); + + _local_6 = ((_local_6 * 7613) + 517); + plane = null; + + if(planeType === RoomPlaneData.PLANE_FLOOR) + { + const _local_15 = ((location.x + leftSide.x) + 0.5); + const _local_16 = ((location.y + rightSide.y) + 0.5); + const _local_17 = (Math.trunc(_local_15) - _local_15); + const _local_18 = (Math.trunc(_local_16) - _local_16); + + plane = new RoomPlane(this.object.getLocation(), location, leftSide, rightSide, RoomPlane.TYPE_FLOOR, true, secondaryNormals, _local_6, -(_local_17), -(_local_18)); + + if(_local_14.z !== 0) + { + plane.color = RoomVisualization._Str_18544; + } + else + { + plane.color = ((_local_14.x !== 0) ? RoomVisualization._Str_16664 : RoomVisualization._Str_18640); + } + + if(this._data) plane.rasterizer = this._data.floorRasterizer; + } + + else if(planeType === RoomPlaneData.PLANE_WALL) + { + plane = new RoomPlane(this.object.getLocation(), location, leftSide, rightSide, RoomPlane.TYPE_WALL, true, secondaryNormals, _local_6); + + if((leftSide.length < 1) || (rightSide.length < 1)) + { + plane._Str_18448 = false; + } + + if((_local_14.x === 0) && (_local_14.y === 0)) + { + plane.color = RoomVisualization._Str_14868; + } + else + { + if(_local_14.y > 0) + { + plane.color = RoomVisualization._Str_14503; + } + else + { + if(_local_14.y === 0) + { + plane.color = RoomVisualization._Str_15851; + } + else + { + plane.color = RoomVisualization._Str_13715; + } + } + } + + if(this._data) plane.rasterizer = this._data.wallRasterizer; + } + + else if(planeType === RoomPlaneData.PLANE_LANDSCAPE) + { + plane = new RoomPlane(this.object.getLocation(), location, leftSide, rightSide, RoomPlane.TYPE_LANDSCAPE, true, secondaryNormals, _local_6, _local_5, 0, _local_3, _local_4); + + if(_local_14.y > 0) + { + plane.color = RoomVisualization._Str_17403; + } + else + { + if(_local_14.y == 0) + { + plane.color = RoomVisualization._Str_16113; + } + else + { + plane.color = RoomVisualization._Str_18370; + } + } + + if(this._data) plane.rasterizer = this._data.landscapeRasterizer; + + _local_5 = (_local_5 + leftSide.length); + } + + else if(planeType == RoomPlaneData.PLANE_BILLBOARD) + { + plane = new RoomPlane(this.object.getLocation(), location, leftSide, rightSide, RoomPlane.TYPE_WALL, true, secondaryNormals, _local_6); + if(((leftSide.length < 1) || (rightSide.length < 1))) + { + plane._Str_18448 = false; + } + if(((_local_14.x == 0) && (_local_14.y == 0))) + { + plane.color = RoomVisualization._Str_14868; + } + else + { + if(_local_14.y > 0) + { + plane.color = RoomVisualization._Str_14503; + } + else + { + if(_local_14.y == 0) + { + plane.color = RoomVisualization._Str_15851; + } + else + { + plane.color = RoomVisualization._Str_13715; + } + } + } + // if (this._Str_594 != null) + // { + // _local_13.rasterizer = this._Str_594._Str_23913; + // } + } + + + if(plane) + { + plane._Str_16279 = this._data.maskManager; + + let _local_19 = 0; + + while(_local_19 < this._roomPlaneParser.getPlaneMaskCount(index)) + { + const _local_20 = this._roomPlaneParser.getPlaneMaskLeftSideLoc(index, _local_19); + const _local_21 = this._roomPlaneParser.getPlaneMaskRightSideLoc(index, _local_19); + const _local_22 = this._roomPlaneParser.getPlaneMaskLeftSideLength(index, _local_19); + const _local_23 = this._roomPlaneParser.getPlaneMaskRightSideLength(index, _local_19); + + plane._Str_24758(_local_20, _local_21, _local_22, _local_23); + + _local_19++; + } + + this._Str_2540.push(plane); + } + } + else + { + return; + } + + index++; + } + + this._isPlaneSet = true; + this._Str_18024(); + + return true; + } + + protected _Str_18024(): void + { + this.setSpriteCount(this._Str_2540.length); + + let planeIndex = 0; + + while(planeIndex < this._Str_2540.length) + { + const plane = this._Str_2540[planeIndex]; + const sprite = this.getSprite(planeIndex); + + if(plane && sprite && plane._Str_5424 && plane._Str_4968) + { + if((plane.type === RoomPlane.TYPE_WALL) && ((plane._Str_5424.length < 1) || (plane._Str_4968.length < 1))) + { + sprite.alphaTolerance = AlphaTolerance._Str_9268; + } + else + { + sprite.alphaTolerance = AlphaTolerance._Str_9735; + } + + if(plane.type === RoomPlane.TYPE_WALL) + { + sprite.tag = 'plane.wall@' + (planeIndex + 1); + } + + else if(plane.type === RoomPlane.TYPE_FLOOR) + { + sprite.tag = 'plane.floor@' + (planeIndex + 1); + } + + else + { + sprite.tag = 'plane@' + (planeIndex + 1); + } + + sprite.spriteType = RoomObjectSpriteType._Str_8616; + } + + planeIndex++; + } + } + + private _Str_23949(): number + { + let length = 0; + let index = 0; + + while(index < this._roomPlaneParser.planeCount) + { + const type = this._roomPlaneParser.getPlaneType(index); + + if(type === RoomPlaneData.PLANE_LANDSCAPE) + { + const vector = this._roomPlaneParser.getPlaneLeftSide(index); + + length += vector.length; + } + + index++; + } + + return length; + } + + private _Str_23063(): number + { + let length = 0; + let index = 0; + + while(index < this._roomPlaneParser.planeCount) + { + const type = this._roomPlaneParser.getPlaneType(index); + + if(type === RoomPlaneData.PLANE_LANDSCAPE) + { + const vector = this._roomPlaneParser.getPlaneRightSide(index); + + if(vector.length > length) length = vector.length; + } + + index++; + } + + if(length > 5) length = 5; + + return length; + } + + protected updatePlaneTypes(floorType: string, wallType: string, landscapeType: string): boolean + { + if(floorType !== this._floorType) this._floorType = floorType; + else floorType = null; + + if(wallType !== this._wallType) this._wallType = wallType; + else wallType = null; + + if(landscapeType !== this._landscapeType) this._landscapeType = landscapeType; + else landscapeType = null; + + if(!floorType && !wallType && !landscapeType) return false; + + let index = 0; + + while(index < this._Str_2540.length) + { + const plane = this._Str_2540[index]; + + if(plane) + { + if((plane.type === RoomPlane.TYPE_FLOOR) && floorType) + { + plane.id = floorType; + } + + else if((plane.type === RoomPlane.TYPE_WALL) && wallType) + { + plane.id = wallType; + } + + else if((plane.type === RoomPlane.TYPE_LANDSCAPE) && landscapeType) + { + plane.id = landscapeType; + } + } + + index++; + } + + return true; + } + + private updatePlaneVisibility(k: boolean, _arg_2: boolean, _arg_3: boolean): void + { + if((k === this._typeVisibility[RoomPlane.TYPE_FLOOR]) && (_arg_2 === this._typeVisibility[RoomPlane.TYPE_WALL]) && (_arg_3 === this._typeVisibility[RoomPlane.TYPE_LANDSCAPE])) return; + + this._typeVisibility[RoomPlane.TYPE_FLOOR] = k; + this._typeVisibility[RoomPlane.TYPE_WALL] = _arg_2; + this._typeVisibility[RoomPlane.TYPE_LANDSCAPE] = _arg_3; + + this._Str_4864 = []; + this._Str_6648 = []; + } + + protected _Str_16913(k: IRoomGeometry, _arg_2: boolean, _arg_3: number): boolean + { + if(!k || !this.object) return; + + this._Str_5928++; + + if(_arg_2) + { + this._Str_4864 = []; + this._Str_6648 = []; + } + + const _local_8 = (this._Str_4864.length > 0); + + let _local_6 = this._Str_4864; + + if(!this._Str_4864.length) _local_6 = this._Str_2540; + + let depth = 0; + let updated = false; + let index = 0; + + while(index < _local_6.length) + { + let _local_10 = index; + + if(_local_8) _local_10 = this._Str_6648[index]; + + const _local_11 = this.getSprite(_local_10); + + if(_local_11) + { + const _local_12 = _local_6[index]; + + if(_local_12) + { + _local_11.id = _local_12.uniqueId; + + if(_local_12.update(k, _arg_3)) + { + if(_local_12.visible) + { + depth = ((_local_12.relativeDepth + this._Str_24891) + (_local_10 / 1000)); + + if(_local_12.type !== RoomPlane.TYPE_FLOOR) + { + depth = ((_local_12.relativeDepth + this._Str_25403) + (_local_10 / 1000)); + + if((_local_12._Str_5424.length < 1) || (_local_12._Str_4968.length < 1)) + { + depth = (depth + (RoomVisualization._Str_8621 * 0.5)); + } + } + + const _local_14 = ((('plane ' + _local_10) + ' ') + k.scale); + + this._Str_7421(_local_11, _local_12, _local_14, depth); + } + updated = true; + } + if(_local_11.visible != ((_local_12.visible) && (this._typeVisibility[_local_12.type]))) + { + _local_11.visible = (!(_local_11.visible)); + updated = true; + } + if(_local_11.visible) + { + if(!_local_8) + { + this._Str_4864.push(_local_12); + this._Str_6648.push(index); + } + } + } + else + { + _local_11.id = 0; + if(_local_11.visible) + { + _local_11.visible = false; + updated = true; + } + } + } + index++; + } + + return updated; + } + + protected _Str_15935(k: RoomMapMaskData): void + { + if(!k) return; + + this._roomPlaneBitmapMaskParser.initialize(k); + + const _local_4: number[] = []; + const _local_5: number[] = []; + + let _local_6 = false; + let index = 0; + + while(index < this._Str_2540.length) + { + const plane = this._Str_2540[index]; + + if(plane) + { + plane._Str_25213(); + + if(plane.type === RoomPlane.TYPE_LANDSCAPE) _local_4.push(index); + } + + index++; + } + + for(const mask of this._roomPlaneBitmapMaskParser.masks.values()) + { + const maskType = this._roomPlaneBitmapMaskParser._Str_21678(mask); + const maskLocation = this._roomPlaneBitmapMaskParser._Str_19038(mask); + const maskCategory = this._roomPlaneBitmapMaskParser._Str_21644(mask); + + if(maskLocation) + { + let i = 0; + + while(i < this._Str_2540.length) + { + const plane = this._Str_2540[i]; + + if((plane.type === RoomPlane.TYPE_WALL) || (plane.type === RoomPlane.TYPE_LANDSCAPE)) + { + if(plane && plane.location && plane.normal) + { + const _local_14 = Vector3d.dif(maskLocation, plane.location); + const _local_15 = Math.abs(Vector3d.scalarProjection(_local_14, plane.normal)); + + if(_local_15 < 0.01) + { + if(plane._Str_5424 && plane._Str_4968) + { + const _local_16 = Vector3d.scalarProjection(_local_14, plane._Str_5424); + const _local_17 = Vector3d.scalarProjection(_local_14, plane._Str_4968); + + if((plane.type === RoomPlane.TYPE_WALL) || ((plane.type === RoomPlane.TYPE_LANDSCAPE) && (maskCategory === RoomPlaneBitmapMaskData.HOLE))) + { + plane._Str_24569(maskType, _local_16, _local_17); + } + else + { + if(plane.type === RoomPlane.TYPE_LANDSCAPE) + { + if(!plane._Str_14801) _local_6 = true; + + plane._Str_14801 = true; + + _local_5.push(i); + } + } + } + } + } + } + + i++; + } + } + } + + index = 0; + + while(index < _local_4.length) + { + const planeIndex = _local_4[index]; + + if(_local_5.indexOf(planeIndex) < 0) + { + const plane = this._Str_2540[planeIndex]; + + plane._Str_14801 = false; + _local_6 = true; + } + + index++; + } + + if(_local_6) + { + this._Str_4864 = []; + this._Str_6648 = []; + } + } + + private _Str_7421(k: IRoomObjectSprite, _arg_2: RoomPlane, _arg_3: string, _arg_4: number): void + { + const offset = _arg_2.offset; + + k.offsetX = -(offset.x); + k.offsetY = -(offset.y); + k.relativeDepth = _arg_4; + k.color = _arg_2.color; + k.texture = this._Str_22446(_arg_2, _arg_3); + k.name = ((_arg_3 + '_') + this._Str_5928); + } + + private _Str_22446(k: RoomPlane, _arg_2: string): Texture + { + return k.bitmapData; + } + + public getBoundingRectangle(): Rectangle + { + if(!this._boundingRectangle) this._boundingRectangle = super.getBoundingRectangle(); + + return new Rectangle(this._boundingRectangle.x, this._boundingRectangle.y, this._boundingRectangle.width, this._boundingRectangle.height); + } + + public get _Str_19113(): IRoomPlane[] + { + const planes: IRoomPlane[] = []; + + for(const plane of this._Str_4864) planes.push(plane); + + return planes; + } + + public get _Str_24891(): number + { + return RoomVisualization._Str_8621 + 0.1; + } + + public get _Str_25403(): number + { + return RoomVisualization._Str_8621 + 0.5; + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/room/RoomVisualizationData.ts b/src/nitro/room/object/visualization/room/RoomVisualizationData.ts new file mode 100644 index 00000000..3e94b1b1 --- /dev/null +++ b/src/nitro/room/object/visualization/room/RoomVisualizationData.ts @@ -0,0 +1,127 @@ +import { IAssetData } from '../../../../../core/asset/interfaces'; +import { Disposable } from '../../../../../core/common/disposable/Disposable'; +import { IObjectVisualizationData } from '../../../../../room/object/visualization/IRoomObjectVisualizationData'; +import { IGraphicAssetCollection } from '../../../../../room/object/visualization/utils/IGraphicAssetCollection'; +import { PlaneMaskManager } from './mask/PlaneMaskManager'; +import { LandscapeRasterizer } from './rasterizer/animated/LandscapeRasterizer'; +import { FloorRasterizer } from './rasterizer/basic/FloorRasterizer'; +import { WallRasterizer } from './rasterizer/basic/WallRasterizer'; + +export class RoomVisualizationData extends Disposable implements IObjectVisualizationData +{ + private _wallRasterizer: WallRasterizer; + private _floorRasterizer: FloorRasterizer; + private _landscapeRasterizer: LandscapeRasterizer; + private _maskManager: PlaneMaskManager; + private _initialized: boolean; + + constructor() + { + super(); + + this._wallRasterizer = new WallRasterizer(); + this._floorRasterizer = new FloorRasterizer(); + this._landscapeRasterizer = new LandscapeRasterizer(); + this._maskManager = new PlaneMaskManager(); + this._initialized = false; + } + + public initialize(asset: IAssetData): boolean + { + //@ts-ignore + const wallData = asset.wallData; + + if(wallData) this._wallRasterizer.initialize(wallData); + + //@ts-ignore + const floorData = asset.floorData; + + if(floorData) this._floorRasterizer.initialize(floorData); + + //@ts-ignore + const landscapeData = asset.landscapeData; + + if(landscapeData) this._landscapeRasterizer.initialize(landscapeData); + + //@ts-ignore + const maskData = asset.maskData; + + if(maskData) this._maskManager.initialize(maskData); + + return true; + } + + protected onDispose(): void + { + if(this._wallRasterizer) + { + this._wallRasterizer.dispose(); + + this._wallRasterizer = null; + } + + if(this._floorRasterizer) + { + this._floorRasterizer.dispose(); + + this._floorRasterizer = null; + } + + if(this._landscapeRasterizer) + { + this._landscapeRasterizer.dispose(); + + this._landscapeRasterizer = null; + } + + if(this._maskManager) + { + this._maskManager.dispose(); + + this._maskManager = null; + } + + super.onDispose(); + } + + public setGraphicAssetCollection(collection: IGraphicAssetCollection): void + { + if(this._initialized) return; + + this._wallRasterizer._Str_6703(collection); + this._floorRasterizer._Str_6703(collection); + this._landscapeRasterizer._Str_6703(collection); + this._maskManager._Str_6703(collection); + + this._initialized = true; + } + + public _Str_3355(): void + { + if(this._wallRasterizer) this._wallRasterizer._Str_3355(); + + if(this._floorRasterizer) this._floorRasterizer._Str_3355(); + + if(this._landscapeRasterizer) this._landscapeRasterizer._Str_3355(); + } + + public get wallRasterizer(): WallRasterizer + { + return this._wallRasterizer; + } + + public get floorRasterizer(): FloorRasterizer + { + return this._floorRasterizer; + } + + public get landscapeRasterizer(): LandscapeRasterizer + { + return this._landscapeRasterizer; + } + + public get maskManager(): PlaneMaskManager + { + return this._maskManager; + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/room/TileCursorVisualization.ts b/src/nitro/room/object/visualization/room/TileCursorVisualization.ts new file mode 100644 index 00000000..5ca24676 --- /dev/null +++ b/src/nitro/room/object/visualization/room/TileCursorVisualization.ts @@ -0,0 +1,26 @@ +import { RoomObjectVariable } from '../../RoomObjectVariable'; +import { FurnitureAnimatedVisualization } from '../furniture/FurnitureAnimatedVisualization'; + +export class TileCursorVisualization extends FurnitureAnimatedVisualization +{ + private _tileHeight: number; + + constructor() + { + super(); + + this._tileHeight = 0; + } + + protected getLayerYOffset(scale: number, direction: number, layerId: number): number + { + if(layerId === 1) + { + this._tileHeight = this.object.model.getValue(RoomObjectVariable.TILE_CURSOR_HEIGHT); + + return -(this._tileHeight) * 32; // 32 = scale / 2 + } + + return super.getLayerYOffset(scale, direction, layerId); + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/room/mask/PlaneMask.ts b/src/nitro/room/object/visualization/room/mask/PlaneMask.ts new file mode 100644 index 00000000..877850ca --- /dev/null +++ b/src/nitro/room/object/visualization/room/mask/PlaneMask.ts @@ -0,0 +1,118 @@ +import { IGraphicAsset } from '../../../../../../room/object/visualization/utils/IGraphicAsset'; +import { IVector3D } from '../../../../../../room/utils/IVector3D'; +import { PlaneMaskVisualization } from './PlaneMaskVisualization'; + +export class PlaneMask +{ + private _maskVisualizations: Map; + private _sizes: number[]; + private _assetNames: Map; + private _lastMaskVisualization: PlaneMaskVisualization; + private _lastSize: number; + + constructor() + { + this._sizes = []; + this._maskVisualizations = new Map(); + this._assetNames = new Map(); + this._lastMaskVisualization = null; + this._lastSize = -1; + } + + public dispose(): void + { + if(this._maskVisualizations) + { + for(const mask of this._maskVisualizations.values()) + { + if(!mask) continue; + + mask.dispose(); + } + + this._maskVisualizations = null; + } + + this._lastMaskVisualization = null; + this._sizes = null; + } + + public _Str_24540(size: number): PlaneMaskVisualization + { + const existing = this._maskVisualizations.get(size); + + if(existing) return null; + + const visualization = new PlaneMaskVisualization(); + + this._maskVisualizations.set(size, visualization); + + this._sizes.push(size); + this._sizes.sort(); + + return visualization; + } + + private _Str_8560(k: number): number + { + let sizeIndex = 0; + const index = 1; + + while(index < this._sizes.length) + { + if(this._sizes[index] > k) + { + if((this._sizes[index] - k) < (k - this._sizes[(index - 1)])) sizeIndex = index; + + break; + } + + sizeIndex = index; + } + + return sizeIndex; + } + + protected _Str_24650(k: number): PlaneMaskVisualization + { + if(k === this._lastSize) return this._lastMaskVisualization; + + const sizeIndex = this._Str_8560(k); + + if(sizeIndex < this._sizes.length) + { + this._lastMaskVisualization = (this._maskVisualizations.get(this._sizes[sizeIndex])); + } + else + { + this._lastMaskVisualization = null; + } + + this._lastSize = k; + + return this._lastMaskVisualization; + } + + public _Str_21021(k: number, _arg_2: IVector3D): IGraphicAsset + { + const visualization = this._Str_24650(k); + + if(!visualization) return null; + + return visualization.getAsset(_arg_2); + } + + public _Str_2125(k: number): string + { + if(!this._assetNames) return null; + + return this._assetNames.get(k) || null; + } + + public _Str_24425(k: number, _arg_2: string): void + { + if(!this._assetNames) return; + + this._assetNames.set(k, _arg_2); + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/room/mask/PlaneMaskBitmap.ts b/src/nitro/room/object/visualization/room/mask/PlaneMaskBitmap.ts new file mode 100644 index 00000000..bb7d496b --- /dev/null +++ b/src/nitro/room/object/visualization/room/mask/PlaneMaskBitmap.ts @@ -0,0 +1,52 @@ +import { IGraphicAsset } from '../../../../../../room/object/visualization/utils/IGraphicAsset'; + +export class PlaneMaskBitmap +{ + public static _Str_3268: number = -1; + public static _Str_3271: number = 1; + + private _asset: IGraphicAsset; + private _normalMinX: number; + private _normalMaxX: number; + private _normalMinY: number; + private _normalMaxY: number; + + constructor(k: IGraphicAsset, _arg_2: number = -1, _arg_3: number = 1, _arg_4: number = -1, _arg_5: number = 1) + { + this._normalMinX = _arg_2; + this._normalMaxX = _arg_3; + this._normalMinY = _arg_4; + this._normalMaxY = _arg_5; + this._asset = k; + } + + public get asset(): IGraphicAsset + { + return this._asset; + } + + public get normalMinX(): number + { + return this._normalMinX; + } + + public get normalMaxX(): number + { + return this._normalMaxX; + } + + public get normalMinY(): number + { + return this._normalMinY; + } + + public get normalMaxY(): number + { + return this._normalMaxY; + } + + public dispose(): void + { + this._asset = null; + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/room/mask/PlaneMaskManager.ts b/src/nitro/room/object/visualization/room/mask/PlaneMaskManager.ts new file mode 100644 index 00000000..315d9148 --- /dev/null +++ b/src/nitro/room/object/visualization/room/mask/PlaneMaskManager.ts @@ -0,0 +1,196 @@ +import { Graphics, Matrix, Point } from 'pixi.js'; +import { IGraphicAssetCollection } from '../../../../../../room/object/visualization/utils/IGraphicAssetCollection'; +import { IVector3D } from '../../../../../../room/utils/IVector3D'; +import { PlaneMask } from './PlaneMask'; +import { PlaneMaskVisualization } from './PlaneMaskVisualization'; + +export class PlaneMaskManager +{ + private _assetCollection: IGraphicAssetCollection; + private _masks: Map; + private _data: any; + + constructor() + { + this._assetCollection = null; + this._masks = new Map(); + this._data = null; + } + + public get data(): any + { + return this._data; + } + + public dispose(): void + { + this._assetCollection = null; + this._data = null; + + if(this._masks && this._masks.size) + { + for(const mask of this._masks.values()) + { + if(!mask) continue; + + mask.dispose(); + } + + this._masks.clear(); + } + } + + public initialize(k: any): void + { + this._data = k; + } + + public _Str_6703(k: IGraphicAssetCollection): void + { + if(!this.data) return; + + this._assetCollection = k; + + this._Str_22834(this.data, k); + } + + private _Str_22834(k: any, _arg_2: IGraphicAssetCollection): void + { + if(!k || !_arg_2) return; + + if(k.masks && k.masks.length) + { + let index = 0; + + while(index < k.masks.length) + { + const mask = k.masks[index]; + + if(mask) + { + const id = mask.id; + const existing = this._masks.get(id); + + if(existing) continue; + + const newMask = new PlaneMask(); + + if(mask.visualizations && mask.visualizations.length) + { + let visualIndex = 0; + + while(visualIndex < mask.visualizations.length) + { + const visualization = mask.visualizations[visualIndex]; + + if(visualization) + { + const size = visualization.size as number; + const maskVisualization = newMask._Str_24540(size); + + if(maskVisualization) + { + const assetName = this._Str_25815(visualization.bitmaps, maskVisualization, _arg_2); + + newMask._Str_24425(size, assetName); + } + } + + visualIndex++; + } + } + + this._masks.set(id, newMask); + } + + index++; + } + } + } + + private _Str_25815(k: any, _arg_2: PlaneMaskVisualization, _arg_3: IGraphicAssetCollection): string + { + if(!k || !k.length) return null; + + let graphicName: string = null; + + for(const bitmap of k) + { + if(!bitmap) continue; + + const assetName = bitmap.assetName; + const asset = _arg_3.getAsset(assetName); + + if(!asset) continue; + + let normalMinX = PlaneMaskVisualization._Str_3268; + let normalMaxX = PlaneMaskVisualization._Str_3271; + let normalMinY = PlaneMaskVisualization._Str_3268; + let normalMaxY = PlaneMaskVisualization._Str_3271; + + if(bitmap.normalMinX !== undefined) normalMinX = bitmap.normalMinX; + if(bitmap.normalMaxX !== undefined) normalMaxX = bitmap.normalMaxX; + if(bitmap.normalMinY !== undefined) normalMinY = bitmap.normalMinY; + if(bitmap.normalMaxY !== undefined) normalMaxY = bitmap.normalMaxY; + + if(!asset.flipH) graphicName = assetName; + + _arg_2._Str_16790(asset, normalMinX, normalMaxX, normalMinY, normalMaxY); + } + + return graphicName; + } + + public _Str_17859(k: Graphics, _arg_2: string, _arg_3: number, _arg_4: IVector3D, _arg_5: number, _arg_6: number): boolean + { + const mask = this._masks.get(_arg_2); + + if(!mask) return true; + + const asset = mask._Str_21021(_arg_3, _arg_4); + + if(!asset) return true; + + const texture = asset.texture; + + if(!texture) return true; + + const point = new Point((_arg_5 + asset.offsetX), (_arg_6 + asset.offsetY)); + + const matrix = new Matrix(); + + let a = 1; + let b = 1; + let c = 0; + let d = 0; + + if(asset.flipH) + { + a = -1; + c = -(texture.width); + } + + if(asset.flipV) + { + b = -1; + d = -(texture.height); + } + + matrix.scale(a, b); + matrix.translate((point.x + c), (point.y + d)); + + k + .beginTextureFill({ texture, matrix }) + .drawRect(matrix.tx, matrix.ty, texture.width, texture.height) + .endFill(); + + return true; + } + + public _Str_8361(k: string): PlaneMask + { + if(!this._masks || !this._masks.size) return null; + + return this._masks.get(k) || null; + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/room/mask/PlaneMaskVisualization.ts b/src/nitro/room/object/visualization/room/mask/PlaneMaskVisualization.ts new file mode 100644 index 00000000..84068357 --- /dev/null +++ b/src/nitro/room/object/visualization/room/mask/PlaneMaskVisualization.ts @@ -0,0 +1,50 @@ +import { IGraphicAsset } from '../../../../../../room/object/visualization/utils/IGraphicAsset'; +import { IVector3D } from '../../../../../../room/utils/IVector3D'; +import { PlaneMaskBitmap } from './PlaneMaskBitmap'; + +export class PlaneMaskVisualization +{ + public static _Str_3268: number = -1; + public static _Str_3271: number = 1; + + private _bitmaps: PlaneMaskBitmap[]; + + constructor() + { + this._bitmaps = []; + } + + public dispose(): void + { + for(const mask of this._bitmaps) + { + if(!mask) continue; + + mask.dispose(); + } + + this._bitmaps = null; + } + + public _Str_16790(k: IGraphicAsset, _arg_2: number = -1, _arg_3: number = 1, _arg_4: number = -1, _arg_5: number = 1): void + { + this._bitmaps.push(new PlaneMaskBitmap(k, _arg_2, _arg_3, _arg_4, _arg_5)); + } + + public getAsset(k: IVector3D): IGraphicAsset + { + if(!k) return null; + + for(const mask of this._bitmaps) + { + if(!mask) continue; + + if((((k.x >= mask.normalMinX) && (k.x <= mask.normalMaxX)) && (k.y >= mask.normalMinY)) && (k.y <= mask.normalMaxY)) + { + return mask.asset; + } + } + + return null; + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/room/rasterizer/IPlaneRasterizer.ts b/src/nitro/room/object/visualization/room/rasterizer/IPlaneRasterizer.ts new file mode 100644 index 00000000..16007f64 --- /dev/null +++ b/src/nitro/room/object/visualization/room/rasterizer/IPlaneRasterizer.ts @@ -0,0 +1,13 @@ +import { Graphics } from 'pixi.js'; +import { IVector3D } from '../../../../../../room/utils/IVector3D'; +import { PlaneBitmapData } from '../utils/PlaneBitmapData'; +import { PlaneVisualizationLayer } from './basic/PlaneVisualizationLayer'; + +export interface IPlaneRasterizer +{ + initializeDimensions(_arg_1: number, _arg_2: number): boolean; + render(_arg_1: Graphics, _arg_2: string, _arg_3: number, _arg_4: number, _arg_5: number, _arg_6: IVector3D, _arg_7: boolean, _arg_8?: number, _arg_9?: number, _arg_10?: number, _arg_11?: number, _arg_12?: number): PlaneBitmapData; + getTextureIdentifier(_arg_1: number, _arg_2: IVector3D): string; + _Str_8988(_arg_1: string): PlaneVisualizationLayer[]; + _Str_24005(): void; +} diff --git a/src/nitro/room/object/visualization/room/rasterizer/animated/AnimationItem.ts b/src/nitro/room/object/visualization/room/rasterizer/animated/AnimationItem.ts new file mode 100644 index 00000000..fdc92022 --- /dev/null +++ b/src/nitro/room/object/visualization/room/rasterizer/animated/AnimationItem.ts @@ -0,0 +1,53 @@ +import { Point } from 'pixi.js'; +import { IGraphicAsset } from '../../../../../../../room/object/visualization/utils/IGraphicAsset'; + +export class AnimationItem +{ + private _x: number; + private _y: number; + private _speedX: number; + private _speedY: number; + private _bitmapData: IGraphicAsset; + + constructor(k: number, _arg_2: number, _arg_3: number, _arg_4: number, _arg_5: IGraphicAsset) + { + this._x = k; + this._y = _arg_2; + this._speedX = _arg_3; + this._speedY = _arg_4; + this._bitmapData = _arg_5; + + if(isNaN(this._x)) this._x = 0; + + if(isNaN(this._y)) this._y = 0; + + if(isNaN(this._speedX)) this._speedX = 0; + + if(isNaN(this._speedY)) this._speedY = 0; + } + + public get bitmapData(): IGraphicAsset + { + return this._bitmapData; + } + + public dispose(): void + { + this._bitmapData = null; + } + + public _Str_6729(k: number, _arg_2: number, _arg_3: number, _arg_4: number, _arg_5: number): Point + { + let _local_6 = this._x; + let _local_7 = this._y; + + if(_arg_3 > 0) _local_6 = (_local_6 + (((this._speedX / _arg_3) * _arg_5) / 1000)); + + if(_arg_4 > 0) _local_7 = (_local_7 + (((this._speedY / _arg_4) * _arg_5) / 1000)); + + const _local_8 = ((_local_6 % 1) * k); + const _local_9 = ((_local_7 % 1) * _arg_2); + + return new Point(_local_8, _local_9); + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/room/rasterizer/animated/LandscapePlane.ts b/src/nitro/room/object/visualization/room/rasterizer/animated/LandscapePlane.ts new file mode 100644 index 00000000..26871fc6 --- /dev/null +++ b/src/nitro/room/object/visualization/room/rasterizer/animated/LandscapePlane.ts @@ -0,0 +1,62 @@ +import { Graphics } from 'pixi.js'; +import { IVector3D } from '../../../../../../../room/utils/IVector3D'; +import { Vector3d } from '../../../../../../../room/utils/Vector3d'; +import { Plane } from '../basic/Plane'; + +export class LandscapePlane extends Plane +{ + public static _Str_2531: number = 0xFFFFFF; + public static _Str_5433: number = 45; + public static _Str_5509: number = 30; + + private _width: number = 0; + private _height: number = 0; + + public isStatic(k: number): boolean + { + const _local_2 = this._Str_6009(k); + + if(_local_2) return !(_local_2._Str_20530); + + return super.isStatic(k); + } + + public initializeDimensions(k: number, _arg_2: number): void + { + if(k < 0) k = 0; + + if(_arg_2 < 0) _arg_2 = 0; + + if((k !== this._width) || (_arg_2 !== this._height)) + { + this._width = k; + this._height = _arg_2; + } + } + + public render(k: Graphics, _arg_2: number, _arg_3: number, _arg_4: number, _arg_5: IVector3D, _arg_6: boolean, _arg_7: number, _arg_8: number, _arg_9: number, _arg_10: number, _arg_11: number): Graphics + { + const visualization = this._Str_6009(_arg_4); + + if(!visualization || !visualization.geometry) return null; + + const _local_13 = visualization.geometry.getScreenPoint(new Vector3d(0, 0, 0)); + const _local_14 = visualization.geometry.getScreenPoint(new Vector3d(0, 0, 1)); + const _local_15 = visualization.geometry.getScreenPoint(new Vector3d(0, 1, 0)); + + if(_local_13 && _local_14 && _local_15) + { + _arg_2 = Math.round(Math.abs((((_local_13.x - _local_15.x) * _arg_2) / visualization.geometry.scale))); + _arg_3 = Math.round(Math.abs((((_local_13.y - _local_14.y) * _arg_3) / visualization.geometry.scale))); + + const _local_16 = (_arg_7 * Math.abs((_local_13.x - _local_15.x))); + const _local_17 = (_arg_8 * Math.abs((_local_13.y - _local_14.y))); + const _local_18 = (_arg_9 * Math.abs((_local_13.x - _local_15.x))); + const _local_19 = (_arg_10 * Math.abs((_local_13.y - _local_14.y))); + + return visualization.render(k, _arg_2, _arg_3, _arg_5, _arg_6, _local_16, _local_17, _local_18, _local_19, _arg_9, _arg_10, _arg_11); + } + + return null; + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/room/rasterizer/animated/LandscapeRasterizer.ts b/src/nitro/room/object/visualization/room/rasterizer/animated/LandscapeRasterizer.ts new file mode 100644 index 00000000..a92909d7 --- /dev/null +++ b/src/nitro/room/object/visualization/room/rasterizer/animated/LandscapeRasterizer.ts @@ -0,0 +1,247 @@ +import { Graphics } from 'pixi.js'; +import { IVector3D } from '../../../../../../../room/utils/IVector3D'; +import { Nitro } from '../../../../../../Nitro'; +import { PlaneBitmapData } from '../../utils/PlaneBitmapData'; +import { Randomizer } from '../../utils/Randomizer'; +import { PlaneMaterial } from '../basic/PlaneMaterial'; +import { PlaneRasterizer } from '../basic/PlaneRasterizer'; +import { PlaneVisualizationLayer } from '../basic/PlaneVisualizationLayer'; +import { LandscapePlane } from './LandscapePlane'; + +export class LandscapeRasterizer extends PlaneRasterizer +{ + private static _Str_3536: number = 500; + + private _landscapeWidth: number = 0; + private _landscapeHeight: number = 0; + + public initializeDimensions(k: number, _arg_2: number): boolean + { + if(k < 0) k = 0; + + if(_arg_2 < 0) _arg_2 = 0; + + this._landscapeWidth = k; + this._landscapeHeight = _arg_2; + + return true; + } + + protected initializePlanes(): void + { + if(!this.data) return; + + const landscapes = this.data.landscapes; + + if(landscapes && landscapes.length) this._Str_25478(landscapes); + } + + private _Str_25478(k: any): void + { + if(!k) return; + + const randomNumber = Math.trunc((Math.random() * 654321)); + + for(const landscapeIndex in k) + { + const landscape = k[landscapeIndex]; + + if(!landscape) continue; + + const id = landscape.id; + const visualizations = landscape.animatedVisualizations; + + const plane = new LandscapePlane(); + + for(const visualization of visualizations) + { + if(!visualization) continue; + + const size = visualization.size; + + let horizontalAngle = LandscapePlane._Str_5433; + let verticalAngle = LandscapePlane._Str_5509; + + if(visualization.horizontalAngle) horizontalAngle = visualization.horizontalAngle; + if(visualization.verticalAngle) verticalAngle = visualization.verticalAngle; + + const basicLayers = visualization.layers; + const animatedLayers = visualization.animationLayers; + const totalBasicLayers = ((basicLayers && basicLayers.length) || 0); + const totalAnimatedLayers = ((animatedLayers && animatedLayers.length) || 0); + const totalLayers = (totalBasicLayers + totalAnimatedLayers); + + const planeVisualization = plane._Str_20305(size, (totalLayers || 0), this._Str_17204(size, horizontalAngle, verticalAngle)); + + if(planeVisualization) + { + Randomizer._Str_17384(randomNumber); + + let layerId = 0; + + if(totalBasicLayers) + { + while(layerId < basicLayers.length) + { + const layer = basicLayers[layerId]; + + if(layer) + { + let material: PlaneMaterial = null; + let align: number = PlaneVisualizationLayer._Str_6914; + let color: number = LandscapePlane._Str_2531; + let offset: number = PlaneVisualizationLayer._Str_1934; + + if(layer.materialId) material = this._Str_8547(layer.materialId); + + if(layer.color) color = layer.color; + + if(layer.offset) offset = layer.offset; + + if(layer.align) + { + if(layer.align === 'bottom') + { + align = PlaneVisualizationLayer._Str_3606; + } + + else if(layer.align === 'top') align = PlaneVisualizationLayer.ALIGN_TOP; + } + + planeVisualization._Str_21464(layerId, material, color, align, offset); + } + + layerId++; + } + } + + layerId = 0; + + if(totalAnimatedLayers) + { + const animationItems: {}[] = []; + + while(layerId < animatedLayers.length) + { + const layer = animatedLayers[layerId]; + + if(layer) + { + const items = layer.animationItems; + + if(items && items.length) + { + for(const item of items) + { + if(item) + { + const id = item.id; + const assetId = item.assetId; + const x = this._Str_21504(item.x || '', item.randomX || ''); + const y = this._Str_21504(item.y || '', item.randomY || ''); + const speedX = item.speedX ? item.speedX / Nitro.instance.getConfiguration('animation.fps') : 0; + const speedY = item.speedY ? item.speedY / Nitro.instance.getConfiguration('animation.fps') : 0; + + animationItems.push({ + asset: assetId, + x, + y, + speedX, + speedY + }); + } + } + } + } + + layerId++; + } + + planeVisualization._Str_23489(layerId, animationItems, this._Str_2697); + } + } + } + + if(!this._Str_3453(id, plane)) plane.dispose(); + } + } + + private _Str_21504(k: string, _arg_2: string): number + { + let _local_3 = 0; + + if((k.length > 0)) + { + if(k.charAt((k.length - 1)) === '%') + { + k = k.substr(0, (k.length - 1)); + + _local_3 = (parseFloat(k) / 100); + } + } + + if((_arg_2.length > 0)) + { + const _local_4 = 10000; + const _local_5 = Randomizer._Str_1612(1, 0, _local_4); + const _local_6 = (_local_5[0] / _local_4); + + if(_arg_2.charAt((_arg_2.length - 1)) === '%') + { + _arg_2 = _arg_2.substr(0, (_arg_2.length - 1)); + + _local_3 = (_local_3 + ((_local_6 * parseFloat(_arg_2)) / 100)); + } + } + + return _local_3; + } + + public render(canvas: Graphics, id: string, width: number, height: number, scale: number, normal: IVector3D, useTexture: boolean, offsetX: number = 0, offsetY: number = 0, maxX: number = 0, maxY: number = 0, timeSinceStartMs: number = 0): PlaneBitmapData + { + let plane = this._Str_3491(id) as LandscapePlane; + + if(!plane) plane = this._Str_3491(LandscapeRasterizer.DEFAULT) as LandscapePlane; + + if(!plane) return null; + + if(canvas) + { + canvas.clear(); + } + + let graphic = plane.render(canvas, width, height, scale, normal, useTexture, offsetX, offsetY, maxX, maxY, timeSinceStartMs); + + if(graphic && (graphic !== canvas)) + { + graphic = graphic.clone(); + + if(!graphic) return null; + } + + let planeBitmapData: PlaneBitmapData = null; + + if(!plane.isStatic(scale) && (LandscapeRasterizer._Str_3536 > 0)) + { + planeBitmapData = new PlaneBitmapData(graphic, ((Math.round((timeSinceStartMs / LandscapeRasterizer._Str_3536)) * LandscapeRasterizer._Str_3536) + LandscapeRasterizer._Str_3536)); + } + else + { + planeBitmapData = new PlaneBitmapData(graphic, -1); + } + + return planeBitmapData; + } + + public getTextureIdentifier(k: number, _arg_2: IVector3D): string + { + if(_arg_2) + { + if(_arg_2.x < 0) return (k + '_0'); + + return (k + '_1'); + } + + return super.getTextureIdentifier(k, _arg_2); + } +} diff --git a/src/nitro/room/object/visualization/room/rasterizer/animated/PlaneVisualizationAnimationLayer.ts b/src/nitro/room/object/visualization/room/rasterizer/animated/PlaneVisualizationAnimationLayer.ts new file mode 100644 index 00000000..7d1efdb8 --- /dev/null +++ b/src/nitro/room/object/visualization/room/rasterizer/animated/PlaneVisualizationAnimationLayer.ts @@ -0,0 +1,151 @@ +import { Graphics, Matrix } from 'pixi.js'; +import { IDisposable } from '../../../../../../../core/common/disposable/IDisposable'; +import { IGraphicAssetCollection } from '../../../../../../../room/object/visualization/utils/IGraphicAssetCollection'; +import { IVector3D } from '../../../../../../../room/utils/IVector3D'; +import { AnimationItem } from './AnimationItem'; + +export class PlaneVisualizationAnimationLayer implements IDisposable +{ + private _color: number = 0; + private _bitmapData: Graphics = null; + private _isDisposed: boolean = false; + private _items: AnimationItem[]; + + constructor(k: any, _arg_2: IGraphicAssetCollection) + { + this._color = 0; + this._bitmapData = null; + this._isDisposed = false; + this._items = []; + + if(k && _arg_2) + { + for(const item of k) + { + if(!item) continue; + + const assetName = item.asset; + + if(assetName) + { + const asset = _arg_2.getAsset(assetName); + + if(asset) this._items.push(new AnimationItem(item.x, item.y, item.speedX, item.speedY, asset)); + } + } + } + } + + public get disposed(): boolean + { + return this._isDisposed; + } + + public dispose(): void + { + this._isDisposed = true; + + if(this._bitmapData) + { + this._bitmapData.destroy(); + + this._bitmapData = null; + } + + if(this._items) + { + for(const item of this._items) item && item.dispose(); + + this._items = []; + } + } + + public _Str_3355(): void + { + if(this._bitmapData) + { + this._bitmapData.destroy(); + + this._bitmapData = null; + } + } + + public render(k: Graphics, _arg_2: number, _arg_3: number, _arg_4: IVector3D, _arg_5: number, _arg_6: number, _arg_7: number, _arg_8: number, _arg_9: number, _arg_10: number, _arg_11: number): Graphics + { + if((((k == null) || (!(k.width == _arg_2))) || (!(k.height == _arg_3)))) + { + if((((this._bitmapData == null) || (!(this._bitmapData.width == _arg_2))) || (!(this._bitmapData.height == _arg_3)))) + { + if(this._bitmapData != null) + { + this._bitmapData.destroy(); + } + + this._bitmapData = new Graphics() + .drawRect(0, 0, _arg_2, _arg_3); + } + else + { + this._bitmapData + .beginFill(0xFFFFFF) + .drawRect(0, 0, this._bitmapData.width, this._bitmapData.height) + .endFill(); + //this._bitmapData.fillRect(this._bitmapData.rect, 0xFFFFFF); + } + + k = this._bitmapData; + } + + if(((_arg_7 > 0) && (_arg_8 > 0))) + { + let _local_12 = 0; + + while(_local_12 < this._items.length) + { + const _local_13 = (this._items[_local_12] as AnimationItem); + if(_local_13 != null) + { + const _local_14 = _local_13._Str_6729(_arg_7, _arg_8, _arg_9, _arg_10, _arg_11); + + _local_14.x = (_local_14.x - _arg_5); + _local_14.y = (_local_14.y - _arg_6); + + if(_local_13.bitmapData) + { + if(_local_14.x > 0 && (_local_14.x + _local_13.bitmapData.width < k.width)) + { + k + .beginFill(0x00FF00) + .beginTextureFill({ texture: _local_13.bitmapData.texture, matrix: new Matrix(1, 0, 0, 1, _local_14.x, _local_14.y) }) + .drawRect(_local_14.x, _local_14.y, _local_13.bitmapData.width, _local_13.bitmapData.height) + .endFill(); + } + else if(_local_14.x > 0) + { + const difference = k.width - _local_14.x; + k + .beginFill(0x00FF00) + .beginTextureFill({ texture: _local_13.bitmapData.texture, matrix: new Matrix(1, 0, 0, 1, _local_14.x, _local_14.y) }) + .drawRect(_local_14.x, _local_14.y, difference, _local_13.bitmapData.height) + .endFill(); + } + else + { + //if(_local_14.x > -_local_13.bitmapData.width) + const difference = _local_13.bitmapData.width + _local_14.x; + k + .beginFill(0x00FF00) + .beginTextureFill({ texture: _local_13.bitmapData.texture, matrix: new Matrix(1, 0, 0, 1, _local_14.x, _local_14.y) }) + .drawRect(0, _local_14.y, difference, _local_13.bitmapData.height) + .endFill(); + } + } + } + + _local_12++; + } + } + + return k; + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/room/rasterizer/basic/FloorPlane.ts b/src/nitro/room/object/visualization/room/rasterizer/basic/FloorPlane.ts new file mode 100644 index 00000000..edc11a0e --- /dev/null +++ b/src/nitro/room/object/visualization/room/rasterizer/basic/FloorPlane.ts @@ -0,0 +1,38 @@ +import { Graphics } from 'pixi.js'; +import { IVector3D } from '../../../../../../../room/utils/IVector3D'; +import { Vector3d } from '../../../../../../../room/utils/Vector3d'; +import { Plane } from './Plane'; + +export class FloorPlane extends Plane +{ + public static _Str_2531: number = 0xFFFFFF; + public static _Str_5433: number = 45; + public static _Str_5509: number = 30; + + public render(k: Graphics, _arg_2: number, _arg_3: number, size: number, _arg_5: IVector3D, _arg_6: boolean, _arg_7: number, _arg_8: number): Graphics + { + const visualization = this._Str_6009(size); + + if(!visualization || !visualization.geometry) return null; + + const _local_10 = visualization.geometry.getScreenPoint(new Vector3d(0, 0, 0)); + const _local_11 = visualization.geometry.getScreenPoint(new Vector3d(0, (_arg_3 / visualization.geometry.scale), 0)); + const _local_12 = visualization.geometry.getScreenPoint(new Vector3d((_arg_2 / visualization.geometry.scale), 0, 0)); + + let _local_13 = 0; + let _local_14 = 0; + + if(_local_10 && _local_11 && _local_12) + { + _arg_2 = Math.round(Math.abs((_local_10.x - _local_12.x))); + _arg_3 = Math.round(Math.abs((_local_10.x - _local_11.x))); + + const _local_15 = (_local_10.x - visualization.geometry.getScreenPoint(new Vector3d(1, 0, 0)).x); + + _local_13 = (_arg_7 * Math.trunc(Math.abs(_local_15))); + _local_14 = (_arg_8 * Math.trunc(Math.abs(_local_15))); + } + + return visualization.render(k, _arg_2, _arg_3, _arg_5, _arg_6, _local_13, _local_14); + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/room/rasterizer/basic/FloorRasterizer.ts b/src/nitro/room/object/visualization/room/rasterizer/basic/FloorRasterizer.ts new file mode 100644 index 00000000..b0731265 --- /dev/null +++ b/src/nitro/room/object/visualization/room/rasterizer/basic/FloorRasterizer.ts @@ -0,0 +1,65 @@ +import { Graphics } from 'pixi.js'; +import { IVector3D } from '../../../../../../../room/utils/IVector3D'; +import { PlaneBitmapData } from '../../utils/PlaneBitmapData'; +import { FloorPlane } from './FloorPlane'; +import { PlaneRasterizer } from './PlaneRasterizer'; + +export class FloorRasterizer extends PlaneRasterizer +{ + protected initializePlanes(): void + { + if(!this.data) return; + + const floors = this.data.floors; + + if(floors && floors.length) this._Str_24495(floors); + } + + private _Str_24495(k: any): void + { + if(!k) return; + + for(const floorIndex in k) + { + const floor = k[floorIndex]; + + if(!floor) continue; + + const id = floor.id; + const visualization = floor.visualizations; + const plane = new FloorPlane(); + + this._Str_9137(plane, visualization); + + if(!this._Str_3453(id, plane)) plane.dispose(); + } + } + + public render(canvas: Graphics, id: string, width: number, height: number, scale: number, normal: IVector3D, useTexture: boolean, offsetX: number = 0, offsetY: number = 0, maxX: number = 0, maxY: number = 0, timeSinceStartMs: number = 0): PlaneBitmapData + { + let plane = this._Str_3491(id) as FloorPlane; + + if(!plane) plane = this._Str_3491(PlaneRasterizer.DEFAULT) as FloorPlane; + + if(!plane) return null; + + if(canvas) + { + canvas + .beginFill(0xFFFFFF) + .drawRect(0, 0, canvas.width, canvas.height) + .endFill(); + } + + let graphic = plane.render(canvas, width, height, scale, normal, useTexture, offsetX, offsetY); + + if(graphic && (graphic !== canvas)) + { + graphic = graphic.clone(); + + if(!graphic) return null; + } + + return new PlaneBitmapData(graphic, -1); + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/room/rasterizer/basic/Plane.ts b/src/nitro/room/object/visualization/room/rasterizer/basic/Plane.ts new file mode 100644 index 00000000..57ea6726 --- /dev/null +++ b/src/nitro/room/object/visualization/room/rasterizer/basic/Plane.ts @@ -0,0 +1,112 @@ +import { IRoomGeometry } from '../../../../../../../room/utils/IRoomGeometry'; +import { PlaneVisualization } from './PlaneVisualization'; +import { PlaneVisualizationLayer } from './PlaneVisualizationLayer'; + +export class Plane +{ + private _planeVisualizations: Map; + private _sizes: number[]; + private _lastPlaneVisualization: PlaneVisualization; + private _lastSize: number; + + constructor() + { + this._planeVisualizations = new Map(); + this._sizes = []; + this._lastPlaneVisualization = null; + this._lastSize = -1; + } + + public isStatic(k: number): boolean + { + return true; + } + + public dispose(): void + { + for(const visualization of this._planeVisualizations.values()) + { + if(!visualization) continue; + + visualization.dispose(); + } + + this._planeVisualizations = null; + this._lastPlaneVisualization = null; + this._sizes = null; + this._lastSize = -1; + } + + public _Str_3355(): void + { + for(const visualization of this._planeVisualizations.values()) + { + if(!visualization) continue; + + visualization._Str_3355(); + } + } + + public _Str_20305(k: number, _arg_2: number, _arg_3: IRoomGeometry): PlaneVisualization + { + const existing = this._planeVisualizations.get(k.toString()); + + if(existing) return null; + + const plane = new PlaneVisualization(k, _arg_2, _arg_3); + + this._planeVisualizations.set(k.toString(), plane); + + this._sizes.push(k); + this._sizes.sort(); + + return plane; + } + + private _Str_8560(k: number): number + { + let size = 0; + let index = 1; + + while(index < this._sizes.length) + { + if(this._sizes[index] > k) + { + if((this._sizes[index] - k) < (k - this._sizes[(index - 1)])) size = index; + + break; + } + + size = index; + + index++; + } + + return size; + } + + protected _Str_6009(k: number): PlaneVisualization + { + if(k === this._lastSize) return this._lastPlaneVisualization; + + const sizeIndex = this._Str_8560(k); + + if(sizeIndex < this._sizes.length) + { + this._lastPlaneVisualization = this._planeVisualizations.get(this._sizes[sizeIndex].toString()); + } + else + { + this._lastPlaneVisualization = null; + } + + this._lastSize = k; + + return this._lastPlaneVisualization; + } + + public _Str_8988(): PlaneVisualizationLayer[] + { + return this._Str_6009(this._lastSize)._Str_8988(); + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/room/rasterizer/basic/PlaneMaterial.ts b/src/nitro/room/object/visualization/room/rasterizer/basic/PlaneMaterial.ts new file mode 100644 index 00000000..5a62c7ce --- /dev/null +++ b/src/nitro/room/object/visualization/room/rasterizer/basic/PlaneMaterial.ts @@ -0,0 +1,93 @@ +import { Graphics } from 'pixi.js'; +import { IVector3D } from '../../../../../../../room/utils/IVector3D'; +import { PlaneMaterialCellMatrix } from './PlaneMaterialCellMatrix'; + +export class PlaneMaterial +{ + public static _Str_3268: number = -1; + public static _Str_3271: number = 1; + + private _planeMaterialItems: PlaneMaterialCellMatrix[]; + private _isCached: boolean; + + constructor() + { + this._planeMaterialItems = []; + this._isCached = false; + } + + public dispose(): void + { + if(this._planeMaterialItems && this._planeMaterialItems.length) + { + for(const item of this._planeMaterialItems) + { + if(!item) continue; + + item.dispose(); + } + + this._planeMaterialItems = null; + } + + this._isCached = false; + } + + public _Str_3355(): void + { + if(!this._isCached) return; + + if(this._planeMaterialItems && this._planeMaterialItems.length) + { + for(const item of this._planeMaterialItems) + { + if(!item) continue; + + item._Str_3355(); + } + } + + this._isCached = false; + } + + public _Str_24503(k: number, _arg_2: number, _arg_3: number, _arg_4: number = -1, _arg_5: number = 1, _arg_6: number = -1, _arg_7: number = 1): PlaneMaterialCellMatrix + { + const cellMatrix = new PlaneMaterialCellMatrix(k, _arg_2, _arg_3, _arg_4, _arg_5, _arg_6, _arg_7); + + this._planeMaterialItems.push(cellMatrix); + + return cellMatrix; + } + + public _Str_21968(k: IVector3D): PlaneMaterialCellMatrix + { + if(!k) return null; + + if(this._planeMaterialItems && this._planeMaterialItems.length) + { + for(const item of this._planeMaterialItems) + { + if(!item) continue; + + if((((k.x >= item.normalMinX) && (k.x <= item.normalMaxX)) && (k.y >= item.normalMinY)) && (k.y <= item.normalMaxY)) return item; + } + } + + return null; + } + + public render(k: Graphics, _arg_2: number, _arg_3: number, _arg_4: IVector3D, _arg_5: boolean, _arg_6: number, _arg_7: number, _arg_8: boolean): Graphics + { + if(_arg_2 < 1) _arg_2 = 1; + + if(_arg_3 < 1) _arg_3 = 1; + + const cellMatrix = this._Str_21968(_arg_4); + + if(!cellMatrix) return null; + + this._isCached = true; + + return cellMatrix.render(k, _arg_2, _arg_3, _arg_4, _arg_5, _arg_6, _arg_7, _arg_8); + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/room/rasterizer/basic/PlaneMaterialCell.ts b/src/nitro/room/object/visualization/room/rasterizer/basic/PlaneMaterialCell.ts new file mode 100644 index 00000000..02538e3b --- /dev/null +++ b/src/nitro/room/object/visualization/room/rasterizer/basic/PlaneMaterialCell.ts @@ -0,0 +1,242 @@ +import { Graphics, Point, Sprite, TilingSprite } from 'pixi.js'; +import { IGraphicAsset } from '../../../../../../../room/object/visualization/utils/IGraphicAsset'; +import { IVector3D } from '../../../../../../../room/utils/IVector3D'; +import { PlaneTexture } from './PlaneTexture'; + +export class PlaneMaterialCell +{ + private _cachedBitmapData: Graphics; + private _texture: PlaneTexture; + private _extraItemOffsets: Point[]; + private _extraItemAssets: IGraphicAsset[]; + private _extraItemCount: number = 0; + + constructor(k: PlaneTexture, _arg_2: IGraphicAsset[] = null, _arg_3: Point[] = null, _arg_4: number = 0) + { + this._cachedBitmapData = null; + this._texture = k; + this._extraItemOffsets = []; + this._extraItemAssets = []; + this._extraItemCount = 0; + + if(_arg_2 && _arg_2.length && (_arg_4 > 0)) + { + let assetIndex = 0; + + while(assetIndex < _arg_2.length) + { + const graphic = _arg_2[assetIndex]; + + if(graphic) this._extraItemAssets.push(graphic); + + assetIndex++; + } + + if(this._extraItemAssets.length) + { + if(_arg_3) + { + let pointIndex = 0; + + while(pointIndex < _arg_3.length) + { + const point = _arg_3[pointIndex]; + + if(point) this._extraItemOffsets.push(new Point(point.x, point.y)); + + pointIndex++; + } + } + + this._extraItemCount = _arg_4; + } + } + } + + public get isStatic(): boolean + { + return this._extraItemCount == 0; + } + + public dispose(): void + { + if(this._texture) + { + this._texture.dispose(); + + this._texture = null; + } + + if(this._cachedBitmapData) + { + this._cachedBitmapData.destroy(); + + this._cachedBitmapData = null; + } + + this._extraItemAssets = null; + this._extraItemOffsets = null; + this._extraItemCount = 0; + } + + public _Str_3355(): void + { + if(this._cachedBitmapData) + { + this._cachedBitmapData.destroy(); + + this._cachedBitmapData = null; + } + } + + public _Str_9599(k: IVector3D): number + { + if(this._texture) + { + const texture = this._texture._Str_4913(k); + + if(texture) return texture.height; + } + + return 0; + } + + public render(normal: IVector3D, textureOffsetX: number, textureOffsetY: number): Sprite + { + if(!this._texture) return null; + + const texture = this._texture._Str_4913(normal); + + if(!texture) return null; + + let bitmap: Sprite = null; + + if((textureOffsetX !== 0) || (textureOffsetY !== 0)) + { + while(textureOffsetX < 0) textureOffsetX += texture.width; + + while(textureOffsetY < 0) textureOffsetY += texture.height; + + const tiling = new TilingSprite(texture, texture.width, texture.height); + + tiling.tilePosition.x = (textureOffsetX % texture.width); + tiling.tilePosition.y = (textureOffsetY % texture.height); + + tiling.uvRespectAnchor = true; + + if(textureOffsetX) + { + tiling.anchor.x = 1; + tiling.scale.x = -1; + } + + if(textureOffsetY) + { + tiling.anchor.y = 1; + tiling.scale.y = -1; + } + + bitmap = tiling; + } + else + { + bitmap = new Sprite(texture); + } + + if(bitmap) + { + // if(!this.isStatic) + // { + // if(this._cachedBitmapData) + // { + // if((this._cachedBitmapData.width !== bitmap.width) || (this._cachedBitmapData.height !== bitmap.height)) + // { + // this._cachedBitmapData.destroy(); + + // this._cachedBitmapData = null; + // } + // else + // { + // const bitmapTexture = TextureUtils.generateTexture(bitmap, new Rectangle(0, 0, bitmap.width, bitmap.height)); + + // RoomVisualization.RENDER_TEXTURES.push(bitmapTexture); + + // if(bitmapTexture) + // { + // this._cachedBitmapData + // .beginTextureFill({ texture: bitmapTexture }) + // .drawRect(0, 0, bitmapTexture.width, bitmapTexture.height) + // .endFill(); + // } + // } + // } + + // if(!this._cachedBitmapData) this._cachedBitmapData = bitmap.clone(); + + // const limitMin = Math.min(this._extraItemCount, this._extraItemOffsets.length); + // const limitMax = Math.max(this._extraItemCount, this._extraItemOffsets.length); + // const offsetIndexes = Randomizer._Str_23572(this._extraItemCount, limitMax); + + // let i = 0; + + // while (i < limitMin) + // { + // const offset = this._extraItemOffsets[offsetIndexes[i]]; + // const item = this._extraItemAssets[(i % this._extraItemAssets.length)]; + + // if(offset && item) + // { + // const assetTexture = item.texture; + + // if(assetTexture) + // { + // const offsetFinal = new Point((offset.x + item.offsetX), (offset.y + item.offsetY)); + // const flipMatrix = new Matrix(); + + // let x = 1; + // let y = 1; + // let translateX = 0; + // let translateY = 0; + + // if(item.flipH) + // { + // x = -1; + // translateX = assetTexture.width; + // } + + // if(item.flipV) + // { + // y = -1; + // translateY = assetTexture.height; + // } + + // let offsetX = (offsetFinal.x + translateX); + // offsetX = ((offsetX >> 1) << 1); + + // flipMatrix.scale(x, y); + // flipMatrix.translate(offsetX, (offsetFinal.y + translateY)); + + // this._cachedBitmapData + // .beginTextureFill({ texture: assetTexture, matrix: flipMatrix }) + // .drawRect(flipMatrix.tx, flipMatrix.ty, assetTexture.width, assetTexture.height) + // .endFill(); + // } + // } + + // i++; + // } + + // return this._cachedBitmapData; + // } + + return bitmap; + } + + return null; + } + + public _Str_2125(k:IVector3D): string + { + return (this._texture == null) ? null : this._texture._Str_2125(k); + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/room/rasterizer/basic/PlaneMaterialCellColumn.ts b/src/nitro/room/object/visualization/room/rasterizer/basic/PlaneMaterialCellColumn.ts new file mode 100644 index 00000000..aeddf409 --- /dev/null +++ b/src/nitro/room/object/visualization/room/rasterizer/basic/PlaneMaterialCellColumn.ts @@ -0,0 +1,490 @@ +import { Graphics } from 'pixi.js'; +import { IVector3D } from '../../../../../../../room/utils/IVector3D'; +import { Vector3d } from '../../../../../../../room/utils/Vector3d'; +import { PlaneMaterialCell } from './PlaneMaterialCell'; + +export class PlaneMaterialCellColumn +{ + public static _Str_9685: number = 0; + public static _Str_7916: number = 1; + public static _Str_6087: number = 2; + public static _Str_6114: number = 3; + public static _Str_6187: number = 4; + public static _Str_6063: number = 5; + + private _cells: PlaneMaterialCell[]; + private _repeatMode: number; + private _width: number; + private _cachedBitmapData: Graphics; + private _cachedBitmapNormal: Vector3d; + private _cachedBitmapDataOffsetX: number; + private _cachedBitmapDataOffsetY: number; + private _isCached: boolean; + private _isStatic: boolean; + + constructor(k: number, _arg_2: PlaneMaterialCell[], _arg_3: number = 1) + { + this._cells = []; + this._repeatMode = _arg_3; + this._width = (k < 1) ? 1 : k; + this._cachedBitmapData = null; + this._cachedBitmapNormal = null; + this._cachedBitmapDataOffsetX = 0; + this._cachedBitmapDataOffsetY = 0; + this._isCached = false; + this._isStatic = true; + + if(_arg_2 && _arg_2.length) + { + let cellIndex = 0; + + while(cellIndex < _arg_2.length) + { + const cell = _arg_2[cellIndex]; + + if(cell) + { + this._cells.push(cell); + + if(!cell.isStatic) this._isStatic = false; + } + + cellIndex++; + } + } + } + + public get isStatic(): boolean + { + return this._isStatic; + } + + public _Str_24523(): boolean + { + return !(this._repeatMode === PlaneMaterialCellColumn._Str_9685); + } + + public get width(): number + { + return this._width; + } + + public dispose(): void + { + if(this._cells && this._cells.length) + { + for(const cell of this._cells) + { + if(!cell) continue; + + cell.dispose(); + } + + this._cells = null; + } + + if(this._cachedBitmapData) + { + this._cachedBitmapData.destroy(); + + this._cachedBitmapData = null; + } + + if(this._cachedBitmapNormal) this._cachedBitmapNormal = null; + } + + public _Str_3355(): void + { + if(!this._isCached) return; + + if(this._cachedBitmapData) + { + this._cachedBitmapData.destroy(); + + this._cachedBitmapData = null; + } + + if(this._cachedBitmapNormal) + { + this._cachedBitmapNormal.x = 0; + this._cachedBitmapNormal.y = 0; + this._cachedBitmapNormal.z = 0; + } + + if(this._cells && this._cells.length) + { + for(const cell of this._cells) + { + if(!cell) continue; + + cell._Str_3355(); + } + } + + this._isCached = false; + } + + public render(height: number, normal: IVector3D, offsetX: number, offsetY: number): Graphics + { + let ht = 0; + + if(this._repeatMode == PlaneMaterialCellColumn._Str_9685) + { + ht = this._Str_19857(this._cells, normal); + height = ht; + } + + if(!this._cachedBitmapNormal) this._cachedBitmapNormal = new Vector3d(); + + if(this.isStatic) + { + if(this._cachedBitmapData) + { + if((this._cachedBitmapData.height === height) && Vector3d.isEqual(this._cachedBitmapNormal, normal) && (this._cachedBitmapDataOffsetX === offsetX) && (this._cachedBitmapDataOffsetY === offsetY)) + { + return this._cachedBitmapData; + } + + this._cachedBitmapData.destroy(); + + this._cachedBitmapData = null; + } + } + else + { + if(this._cachedBitmapData) + { + if(this._cachedBitmapData.height === height) + { + this._cachedBitmapData + .beginFill(0xFFFFFF) + .drawRect(0, 0, this._cachedBitmapData.width, height) + .endFill(); + } + else + { + this._cachedBitmapData.destroy(); + + this._cachedBitmapData = null; + } + } + } + + this._isCached = true; + + if(!this._cachedBitmapData) + { + this._cachedBitmapData = new Graphics() + .beginFill(0xFFFFFF) + .drawRect(0, 0, this._width, height) + .endFill(); + } + + this._cachedBitmapNormal.assign(normal); + this._cachedBitmapDataOffsetX = offsetX; + this._cachedBitmapDataOffsetY = offsetY; + + if(!this._cells.length) return this._cachedBitmapData; + + switch(this._repeatMode) + { + case PlaneMaterialCellColumn._Str_9685: + this._Str_25839(normal); + break; + case PlaneMaterialCellColumn._Str_6087: + console.log('tru2'); + // this._Str_18476(normal); + break; + case PlaneMaterialCellColumn._Str_6114: + console.log('tru3'); + // this._Str_17295(normal); + break; + case PlaneMaterialCellColumn._Str_6187: + console.log('tru4'); + // this._Str_18019(normal); + break; + case PlaneMaterialCellColumn._Str_6063: + console.log('tru5'); + // this._Str_16099(normal); + break; + default: + this._Str_18711(normal, offsetX, offsetY); + break; + } + + return this._cachedBitmapData; + } + + private _Str_19857(k: PlaneMaterialCell[], _arg_2: IVector3D): number + { + if(!k || !k.length) return 0; + + let height = 0; + let cellIterator = 0; + + while(cellIterator < k.length) + { + const cell = k[cellIterator]; + + if(cell) height += cell._Str_9599(_arg_2); + + cellIterator++; + } + + return height; + } + + private _Str_4757(k: PlaneMaterialCell[], _arg_2: number, _arg_3: boolean, _arg_4: IVector3D, _arg_5: number = 0, _arg_6: number = 0): number + { + if(((!k || !k.length) || !this._cachedBitmapData)) return _arg_2; + + let cellIndex = 0; + + while(cellIndex < k.length) + { + let cell: PlaneMaterialCell = null; + + if(_arg_3) + { + cell = k[cellIndex]; + } + else + { + cell = k[((k.length - 1) - cellIndex)]; + } + + if(cell) + { + const graphic = cell.render(_arg_4, _arg_5, _arg_6); + + if(graphic) + { + if(!_arg_3) _arg_2 -= graphic.height; + + graphic.y = _arg_2; + + this._cachedBitmapData.addChild(graphic); + + if(_arg_3) _arg_2 = (_arg_2 + graphic.height); + + if(((_arg_3) && (_arg_2 >= this._cachedBitmapData.height)) || ((!(_arg_3)) && (_arg_2 <= 0))) return _arg_2; + } + } + + cellIndex++; + } + + return _arg_2; + } + + private _Str_25839(k: IVector3D): void + { + if(!this._cells.length || !this._cachedBitmapData) return; + + this._Str_4757(this._cells, 0, true, k); + } + + private _Str_18711(k: IVector3D, _arg_2: number, _arg_3: number): void + { + if(!this._cells.length || !this._cachedBitmapData) return; + + let index = 0; + + while(index < this._cachedBitmapData.height) + { + index = this._Str_4757(this._cells, index, true, k, _arg_2, _arg_3); + + if(!index) return; + } + } + + // private _Str_18476(k:IVector3D): void + // { + // if (((this._cells.length == 0) || (this._cachedBitmapData == null))) + // { + // return; + // } + // var _local_2:PlaneMaterialCell; + // var _local_3:BitmapData; + // var _local_4:Array = []; + // var _local_5: number; + // var _local_6: number; + // var _local_7: number; + // _local_7 = 1; + // while (_local_7 < (this._cells.length - 1)) + // { + // _local_2 = (this._cells[_local_7] as PlaneMaterialCell); + // if (_local_2 != null) + // { + // _local_6 = _local_2._Str_9599(k); + // if (_local_6 > 0) + // { + // _local_5 = (_local_5 + _local_6); + // _local_4.push(_local_2); + // } + // } + // _local_7++; + // } + // if (this._cells.length == 1) + // { + // _local_2 = (this._cells[0] as PlaneMaterialCell); + // if (_local_2 != null) + // { + // _local_6 = _local_2._Str_9599(k); + // if (_local_6 > 0) + // { + // _local_5 = (_local_5 + _local_6); + // _local_4.push(_local_2); + // } + // } + // } + // var _local_8:* = ((this._cachedBitmapData.height - _local_5) >> 1); + // var _local_9: number = this._Str_4757(_local_4, _local_8, true, k); + // _local_2 = (this._cells[0] as PlaneMaterialCell); + // if (_local_2 != null) + // { + // _local_4 = [_local_2]; + // while (_local_8 >= 0) + // { + // _local_8 = this._Str_4757(_local_4, _local_8, false, k); + // } + // } + // _local_2 = (this._cells[(this._cells.length - 1)] as PlaneMaterialCell); + // if (_local_2 != null) + // { + // _local_4 = [_local_2]; + // while (_local_9 < this._cachedBitmapData.height) + // { + // _local_9 = this._Str_4757(_local_4, _local_9, true, k); + // } + // } + // } + + // private _Str_17295(k:IVector3D): void + // { + // var _local_13: number; + // var _local_14: number; + // var _local_15: number; + // var _local_16:Array; + // if (((this._cells.length == 0) || (this._cachedBitmapData == null))) + // { + // return; + // } + // var _local_2:PlaneMaterialCell; + // var _local_3:BitmapData; + // var _local_4:Array = []; + // var _local_5:Array = []; + // var _local_6: number; + // var _local_7: number; + // var _local_8: number; + // var _local_9: number; + // _local_9 = 0; + // while (_local_9 < (this._cells.length >> 1)) + // { + // _local_2 = (this._cells[_local_9] as PlaneMaterialCell); + // if (_local_2 != null) + // { + // _local_8 = _local_2._Str_9599(k); + // if (_local_8 > 0) + // { + // _local_6 = (_local_6 + _local_8); + // _local_4.push(_local_2); + // } + // } + // _local_9++; + // } + // _local_9 = ((this._cells.length >> 1) + 1); + // while (_local_9 < this._cells.length) + // { + // _local_2 = (this._cells[_local_9] as PlaneMaterialCell); + // if (_local_2 != null) + // { + // _local_8 = _local_2._Str_9599(k); + // if (_local_8 > 0) + // { + // _local_7 = (_local_7 + _local_8); + // _local_5.push(_local_2); + // } + // } + // _local_9++; + // } + // var _local_10: number; + // var _local_11: number; + // var _local_12: number = this._cachedBitmapData.height; + // if ((_local_6 + _local_7) > this._cachedBitmapData.height) + // { + // _local_10 = ((_local_6 + _local_7) - this._cachedBitmapData.height); + // _local_11 = (_local_11 - (_local_10 >> 1)); + // _local_12 = (_local_12 + (_local_10 - (_local_10 >> 1))); + // } + // if (_local_10 == 0) + // { + // _local_2 = (this._cells[(this._cells.length >> 1)] as PlaneMaterialCell); + // if (_local_2 != null) + // { + // _local_8 = _local_2._Str_9599(k); + // if (_local_8 > 0) + // { + // _local_13 = (this._cachedBitmapData.height - (_local_6 + _local_7)); + // _local_14 = (Math.ceil((_local_13 / _local_8)) * _local_8); + // _local_11 = (_local_6 - ((_local_14 - _local_13) >> 1)); + // _local_15 = (_local_11 + _local_14); + // _local_16 = [_local_2]; + // while (_local_11 < _local_15) + // { + // _local_11 = this._Str_4757(_local_16, _local_11, true, k); + // } + // } + // } + // } + // _local_11 = 0; + // this._Str_4757(_local_4, _local_11, true, k); + // this._Str_4757(_local_5, _local_12, false, k); + // } + + // private _Str_18019(k:IVector3D): void + // { + // var _local_4:Array; + // if (((this._cells.length == 0) || (this._cachedBitmapData == null))) + // { + // return; + // } + // var _local_2:PlaneMaterialCell; + // var _local_3: number = this._cachedBitmapData.height; + // _local_3 = this._Str_4757(this._cells, _local_3, false, k); + // _local_2 = (this._cells[0] as PlaneMaterialCell); + // if (_local_2 != null) + // { + // _local_4 = [_local_2]; + // while (_local_3 >= 0) + // { + // _local_3 = this._Str_4757(_local_4, _local_3, false, k); + // } + // } + // } + + // private _Str_16099(k: IVector3D): void + // { + // if(!this._cells.length || !this._cachedBitmapData) return; + + + // var _local_4:Array; + // var _local_2:PlaneMaterialCell; + // var _local_3: number; + // _local_3 = this._Str_4757(this._cells, _local_3, true, k); + // _local_2 = (this._cells[(this._cells.length - 1)] as PlaneMaterialCell); + // if (_local_2 != null) + // { + // _local_4 = [_local_2]; + // while (_local_3 < this._cachedBitmapData.height) + // { + // _local_3 = this._Str_4757(_local_4, _local_3, true, k); + // } + // } + // } + + public _Str_22299(): PlaneMaterialCell[] + { + return this._cells; + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/room/rasterizer/basic/PlaneMaterialCellMatrix.ts b/src/nitro/room/object/visualization/room/rasterizer/basic/PlaneMaterialCellMatrix.ts new file mode 100644 index 00000000..7843c00f --- /dev/null +++ b/src/nitro/room/object/visualization/room/rasterizer/basic/PlaneMaterialCellMatrix.ts @@ -0,0 +1,723 @@ +import { Graphics, Point, Rectangle } from 'pixi.js'; +import { IVector3D } from '../../../../../../../room/utils/IVector3D'; +import { TextureUtils } from '../../../../../../../room/utils/TextureUtils'; +import { Vector3d } from '../../../../../../../room/utils/Vector3d'; +import { RoomVisualization } from '../../RoomVisualization'; +import { Randomizer } from '../../utils/Randomizer'; +import { PlaneMaterialCell } from './PlaneMaterialCell'; +import { PlaneMaterialCellColumn } from './PlaneMaterialCellColumn'; + +export class PlaneMaterialCellMatrix +{ + public static _Str_7916: number = 1; + public static _Str_6087: number = 2; + public static _Str_6114: number = 3; + public static _Str_6187: number = 4; + public static _Str_6063: number = 5; + public static _Str_9127: number = 6; + public static _Str_18632: number = PlaneMaterialCellMatrix._Str_7916;//1 + public static _Str_3268: number = -1; + public static _Str_3271: number = 1; + public static ALIGN_TOP: number = 1; + public static _Str_3606: number = 2; + public static _Str_6914: number = PlaneMaterialCellMatrix.ALIGN_TOP;//1 + + private _columns: PlaneMaterialCellColumn[]; + private _repeatMode: number = 1; + private _align: number = 1; + private _cachedBitmapData: Graphics; + private _cachedBitmapNormal: Vector3d = null; + private _cachedBitmapHeight: number = 0; + private _isCached: boolean = false; + private _isStatic: boolean = true; + private _normalMinX: number = -1; + private _normalMaxX: number = 1; + private _normalMinY: number = -1; + private _normalMaxY: number = 1; + + constructor(k: number, _arg_2: number=1, _arg_3: number=1, _arg_4: number=-1, _arg_5: number=1, _arg_6: number=-1, _arg_7: number=1) + { + this._columns = []; + if(k < 1) + { + k = 1; + } + let _local_8 = 0; + while(_local_8 < k) + { + this._columns.push(null); + _local_8++; + } + this._repeatMode = _arg_2; + this._align = _arg_3; + this._normalMinX = _arg_4; + this._normalMaxX = _arg_5; + this._normalMinY = _arg_6; + this._normalMaxY = _arg_7; + if(this._repeatMode == PlaneMaterialCellMatrix._Str_9127) + { + this._isStatic = false; + } + } + + private static _Str_12526(k: number): number + { + return ((Randomizer._Str_1612(1, 0, (k * 17631))[0]) % k); + } + + public get normalMinX(): number + { + return this._normalMinX; + } + + public get normalMaxX(): number + { + return this._normalMaxX; + } + + public get normalMinY(): number + { + return this._normalMinY; + } + + public get normalMaxY(): number + { + return this._normalMaxY; + } + + public _Str_14945(): boolean + { + return this._align === PlaneMaterialCellMatrix._Str_3606; + } + + public get isStatic(): boolean + { + return this._isStatic; + } + + public dispose(): void + { + if(this._cachedBitmapData) + { + this._cachedBitmapData.destroy(); + + this._cachedBitmapData = null; + } + + if(this._cachedBitmapNormal) this._cachedBitmapNormal = null; + } + + public _Str_3355(): void + { + if(!this._isCached) return; + + if(this._cachedBitmapData) + { + this._cachedBitmapData.destroy(); + + this._cachedBitmapData = null; + } + + if(this._cachedBitmapNormal) + { + this._cachedBitmapNormal.x = 0; + this._cachedBitmapNormal.y = 0; + this._cachedBitmapNormal.z = 0; + } + + if(this._columns && this._columns.length) + { + for(const column of this._columns) + { + if(!column) continue; + + column._Str_3355(); + } + } + + this._isCached = false; + } + + public _Str_22372(k: number, _arg_2: number, _arg_3: PlaneMaterialCell[], _arg_4: number=1): boolean + { + if((k < 0) || (k >= this._columns.length)) return false; + + const newColumn = new PlaneMaterialCellColumn(_arg_2, _arg_3, _arg_4); + const oldColumn = this._columns[k]; + + if(oldColumn) oldColumn.dispose(); + + this._columns[k] = newColumn; + + if(newColumn && !newColumn.isStatic) this._isStatic = false; + + return true; + } + + public render(canvas: Graphics, width: number, height: number, normal: IVector3D, useTexture: boolean, offsetX: number, offsetY: number, topAlign: boolean): Graphics + { + if(width < 1) width = 1; + + if(height < 1) height = 1; + + if(!canvas || (canvas.width !== width) || (canvas.height !== height)) canvas = null; + + if(!this._cachedBitmapNormal) this._cachedBitmapNormal = new Vector3d(); + + if(this.isStatic) + { + if(this._cachedBitmapData) + { + if(((this._cachedBitmapData.width === width) && (this._cachedBitmapData.height == height)) && Vector3d.isEqual(this._cachedBitmapNormal, normal)) + { + if(canvas) + { + this._Str_17578(canvas, this._cachedBitmapHeight, offsetY, topAlign); + + return canvas; + } + + return this._cachedBitmapData; + } + + this._cachedBitmapData.destroy(); + + this._cachedBitmapData = null; + } + } + else + { + if(this._cachedBitmapData) + { + if((this._cachedBitmapData.width === width) && (this._cachedBitmapData.height === height)) + { + this._cachedBitmapData + .beginFill(0xFFFFFF) + .drawRect(0, 0, width, height) + .endFill(); + } + else + { + this._cachedBitmapData.destroy(); + + this._cachedBitmapData = null; + } + } + } + + this._isCached = true; + this._cachedBitmapNormal.assign(normal); + + if(!useTexture) + { + this._cachedBitmapHeight = height; + + if(!this._cachedBitmapData) + { + const graphic = new Graphics() + .beginFill(0xFFFFFF) + .drawRect(0, 0, width, height) + .endFill(); + + this._cachedBitmapData = graphic; + } + else + { + this._cachedBitmapData + .beginFill(0xFFFFFF) + .drawRect(0, 0, width, height) + .endFill(); + } + + if(canvas) + { + this._Str_17578(canvas, height, offsetY, topAlign); + + return canvas; + } + + return this._cachedBitmapData; + } + + if(!this._cachedBitmapData) + { + this._cachedBitmapHeight = height; + + const graphic = new Graphics() + .beginFill(0xFFFFFF) + .drawRect(0, 0, width, height) + .endFill(); + + this._cachedBitmapData = graphic; + } + + const columns: Graphics[] = []; + + let columnIndex = 0; + + while(columnIndex < this._columns.length) + { + const column = this._columns[columnIndex]; + + if(column) + { + const columnBitmapData = column.render(height, normal, offsetX, offsetY); + + if(columnBitmapData) columns.push(columnBitmapData); + } + + columnIndex++; + } + + if(!columns.length) + { + if(canvas) return canvas; + + return this._cachedBitmapData; + } + + let maxColumnHeight = 0; + + switch(this._repeatMode) + { + case PlaneMaterialCellMatrix._Str_6087: + // maxColumnHeight = this._Str_18476(this._cachedBitmapData, columns); + break; + case PlaneMaterialCellMatrix._Str_6114: + // maxColumnHeight = this._Str_17295(this._cachedBitmapData, columns); + break; + case PlaneMaterialCellMatrix._Str_6187: + // maxColumnHeight = this._Str_18019(this._cachedBitmapData, columns); + break; + case PlaneMaterialCellMatrix._Str_6063: + // maxColumnHeight = this._Str_16099(this._cachedBitmapData, columns); + break; + case PlaneMaterialCellMatrix._Str_9127: + // maxColumnHeight = this._Str_25678(this._cachedBitmapData, columns); + break; + default: + maxColumnHeight = this._Str_18711(this._cachedBitmapData, columns); + break; + } + + this._cachedBitmapHeight = maxColumnHeight; + + if(canvas) + { + this._Str_17578(canvas, maxColumnHeight, offsetY, topAlign); + + return canvas; + } + + return this._cachedBitmapData; + } + + private _Str_17578(k: Graphics, _arg_2: number, _arg_3: number, _arg_4: boolean): void + { + if(!k || !this._cachedBitmapData || (k === this._cachedBitmapData)) return; + + if(!_arg_4) _arg_3 = ((k.height - _arg_2) - _arg_3); + + let _local_5: Rectangle; + + if(this._align == PlaneMaterialCellMatrix.ALIGN_TOP) + { + _local_5 = new Rectangle(0, 0, this._cachedBitmapData.width, this._cachedBitmapHeight); + } + else + { + _local_5 = new Rectangle(0, (this._cachedBitmapData.height - this._cachedBitmapHeight), this._cachedBitmapData.width, this._cachedBitmapHeight); + } + + const texture = TextureUtils.generateTexture(this._cachedBitmapData, _local_5); + + if(texture) + { + k + .beginTextureFill({ texture }) + .drawRect(0, _arg_3, _local_5.width, _local_5.height) + .endFill(); + } + } + + private _Str_25859(k: Graphics[]): number + { + if(!k || !k.length) return 0; + + let width = 0; + + for(const graphic of k) + { + if(!graphic) continue; + + width += graphic.width; + } + + return width; + } + + private _Str_4606(k: Graphics, _arg_2: Graphics[], _arg_3: number, _arg_4: boolean): Point + { + if(!k || !_arg_2 || !_arg_2.length) return new Point(_arg_3, 0); + + let height = 0; + let _local_6: Graphics = null; + let _local_7 = 0; + + while(_local_7 < _arg_2.length) + { + if(_arg_4) + { + _local_6 = _arg_2[_local_7]; + } + else + { + _local_6 = _arg_2[((_arg_2.length - 1) - _local_7)]; + } + if(_local_6 != null) + { + if(!_arg_4) + { + _arg_3 = (_arg_3 - _local_6.width); + } + let _local_8 = 0; + if(this._align == PlaneMaterialCellMatrix._Str_3606) + { + _local_8 = (k.height - _local_6.height); + } + + let texture = RoomVisualization.getTextureCache(_local_6); + + if(!texture) + { + texture = TextureUtils.generateTexture(_local_6, new Rectangle(0, 0, _local_6.width, _local_6.height)); + + RoomVisualization.addTextureCache(_local_6, texture); + } + + k.beginTextureFill({ texture }); + k.drawRect(_arg_3, _local_8, texture.width, texture.height); + k.endFill(); + + if(_local_6.height > height) + { + height = _local_6.height; + } + if(_arg_4) + { + _arg_3 = (_arg_3 + _local_6.width); + } + if((((_arg_4) && (_arg_3 >= k.width)) || ((!(_arg_4)) && (_arg_3 <= 0)))) + { + return new Point(_arg_3, height); + } + } + _local_7++; + } + return new Point(_arg_3, height); + } + + private _Str_18711(k: Graphics, _arg_2: Graphics[]): number + { + if(!k || !_arg_2 || !_arg_2.length) return 0; + + const totalWidth: number = this._Str_25859(_arg_2); + + let x = 0; + let y = 0; + + while(x < k.width) + { + const point = this._Str_4606(k, _arg_2, x, true); + + x = point.x; + + if(point.y > y) y = point.y; + + if(!point.x) return y; + } + + return y; + } + + // private _Str_18476(k:BitmapData, _arg_2:Array): number + // { + // if ((((_arg_2 == null) || (_arg_2.length == 0)) || (k == null))) + // { + // return 0; + // } + // var _local_3: number; + // var _local_4:BitmapData; + // var _local_5:Array = []; + // var _local_6: number; + // var _local_7: number; + // _local_7 = 1; + // while (_local_7 < (_arg_2.length - 1)) + // { + // _local_4 = (_arg_2[_local_7] as BitmapData); + // if (_local_4 != null) + // { + // _local_6 = (_local_6 + _local_4.width); + // _local_5.push(_local_4); + // } + // _local_7++; + // } + // if (this._columns.length == 1) + // { + // _local_4 = (this._columns[0] as BitmapData); + // if (_local_4 != null) + // { + // _local_6 = _local_4.width; + // _local_5.push(_local_4); + // } + // } + // var _local_8:* = ((k.width - _local_6) >> 1); + // var _local_9:Point; + // _local_9 = this._Str_4606(k, _local_5, _local_8, true); + // var _local_10: number = _local_9.x; + // if (_local_9.y > _local_3) + // { + // _local_3 = _local_9.y; + // } + // _local_4 = (_arg_2[0] as BitmapData); + // if (_local_4 != null) + // { + // _local_5 = [_local_4]; + // while (_local_8 >= 0) + // { + // _local_9 = this._Str_4606(k, _local_5, _local_8, false); + // _local_8 = _local_9.x; + // if (_local_9.y > _local_3) + // { + // _local_3 = _local_9.y; + // } + // } + // } + // _local_4 = (_arg_2[(_arg_2.length - 1)] as BitmapData); + // if (_local_4 != null) + // { + // _local_5 = [_local_4]; + // while (_local_10 < k.height) + // { + // _local_9 = this._Str_4606(k, _local_5, _local_10, true); + // _local_10 = _local_9.x; + // if (_local_9.y > _local_3) + // { + // _local_3 = _local_9.y; + // } + // } + // } + // return _local_3; + // } + + // private _Str_17295(k:BitmapData, _arg_2:Array): number + // { + // var _local_14: number; + // var _local_15: number; + // var _local_16: number; + // var _local_17: number; + // var _local_18:Array; + // if ((((_arg_2 == null) || (_arg_2.length == 0)) || (k == null))) + // { + // return 0; + // } + // var _local_3: number; + // var _local_4:BitmapData; + // var _local_5:Array = []; + // var _local_6:Array = []; + // var _local_7: number; + // var _local_8: number; + // var _local_9: number; + // _local_9 = 0; + // while (_local_9 < (_arg_2.length >> 1)) + // { + // _local_4 = (_arg_2[_local_9] as BitmapData); + // if (_local_4 != null) + // { + // _local_7 = (_local_7 + _local_4.width); + // _local_5.push(_local_4); + // } + // _local_9++; + // } + // _local_9 = ((_arg_2.length >> 1) + 1); + // while (_local_9 < _arg_2.length) + // { + // _local_4 = (_arg_2[_local_9] as BitmapData); + // if (_local_4 != null) + // { + // _local_8 = (_local_8 + _local_4.width); + // _local_6.push(_local_4); + // } + // _local_9++; + // } + // var _local_10:Point; + // var _local_11: number; + // var _local_12: number; + // var _local_13: number = k.width; + // if ((_local_7 + _local_8) > k.width) + // { + // _local_11 = ((_local_7 + _local_8) - k.width); + // _local_12 = (_local_12 - (_local_11 >> 1)); + // _local_13 = (_local_13 + (_local_11 - (_local_11 >> 1))); + // } + // if (_local_11 == 0) + // { + // _local_4 = (_arg_2[(_arg_2.length >> 1)] as BitmapData); + // if (_local_4 != null) + // { + // _local_14 = _local_4.width; + // _local_15 = (k.width - (_local_7 + _local_8)); + // _local_16 = (Math.ceil((_local_15 / _local_14)) * _local_14); + // _local_12 = (_local_7 - ((_local_16 - _local_15) >> 1)); + // _local_17 = (_local_12 + _local_16); + // _local_18 = [_local_4]; + // while (_local_12 < _local_17) + // { + // _local_10 = this._Str_4606(k, _local_18, _local_12, true); + // _local_12 = _local_10.x; + // if (_local_10.y > _local_3) + // { + // _local_3 = _local_10.y; + // } + // } + // } + // } + // _local_12 = 0; + // _local_10 = this._Str_4606(k, _local_5, _local_12, true); + // if (_local_10.y > _local_3) + // { + // _local_3 = _local_10.y; + // } + // _local_10 = this._Str_4606(k, _local_6, _local_13, false); + // if (_local_10.y > _local_3) + // { + // _local_3 = _local_10.y; + // } + // return _local_3; + // } + + // private _Str_18019(k:BitmapData, _arg_2:Array): number + // { + // var _local_7:Array; + // if ((((_arg_2 == null) || (_arg_2.length == 0)) || (k == null))) + // { + // return 0; + // } + // var _local_3: number; + // var _local_4:BitmapData; + // var _local_5: number = k.width; + // var _local_6:Point = this._Str_4606(k, _arg_2, _local_5, false); + // _local_5 = _local_6.x; + // if (_local_6.y > _local_3) + // { + // _local_3 = _local_6.y; + // } + // _local_4 = (_arg_2[0] as BitmapData); + // if (_local_4 != null) + // { + // _local_7 = [_local_4]; + // while (_local_5 >= 0) + // { + // _local_6 = this._Str_4606(k, _local_7, _local_5, false); + // _local_5 = _local_6.x; + // if (_local_6.y > _local_3) + // { + // _local_3 = _local_6.y; + // } + // } + // } + // return _local_3; + // } + + // private _Str_16099(k:BitmapData, _arg_2:Array): number + // { + // var _local_7:Array; + // if ((((_arg_2 == null) || (_arg_2.length == 0)) || (k == null))) + // { + // return 0; + // } + // var _local_3: number; + // var _local_4:BitmapData; + // var _local_5: number; + // var _local_6:Point = this._Str_4606(k, _arg_2, _local_5, true); + // _local_5 = _local_6.x; + // if (_local_6.y > _local_3) + // { + // _local_3 = _local_6.y; + // } + // _local_4 = (_arg_2[(_arg_2.length - 1)] as BitmapData); + // if (_local_4 != null) + // { + // _local_7 = [_local_4]; + // while (_local_5 < k.width) + // { + // _local_6 = this._Str_4606(k, _local_7, _local_5, true); + // _local_5 = _local_6.x; + // if (_local_6.y > _local_3) + // { + // _local_3 = _local_6.y; + // } + // } + // } + // return _local_3; + // } + + // private _Str_25678(k:BitmapData, _arg_2:Array): number + // { + // var _local_6:Array; + // var _local_7:Point; + // if ((((_arg_2 == null) || (_arg_2.length == 0)) || (k == null))) + // { + // return 0; + // } + // var _local_3: number; + // var _local_4:BitmapData; + // var _local_5: number; + // while (_local_5 < k.width) + // { + // _local_4 = (_arg_2[_Str_12526(_arg_2.length)] as BitmapData); + // if (_local_4 != null) + // { + // _local_6 = [_local_4]; + // _local_7 = this._Str_4606(k, _local_6, _local_5, true); + // _local_5 = _local_7.x; + // if (_local_7.y > _local_3) + // { + // _local_3 = _local_7.y; + // } + // } + // else + // { + // return _local_3; + // } + // } + // return _local_3; + // } + + public _Str_23721(k: number): PlaneMaterialCellColumn[] + { + if(this._repeatMode === PlaneMaterialCellMatrix._Str_9127) + { + const columns: PlaneMaterialCellColumn[] = []; + + let columnIndex = 0; + + while(columnIndex < k) + { + const column = this._columns[PlaneMaterialCellMatrix._Str_12526(this._columns.length)]; + + if(column) + { + columns.push(column); + + if(column.width > 1) columnIndex += column.width; + else break; + } + } + + return columns; + } + + return this._columns; + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/room/rasterizer/basic/PlaneRasterizer.ts b/src/nitro/room/object/visualization/room/rasterizer/basic/PlaneRasterizer.ts new file mode 100644 index 00000000..61a601bd --- /dev/null +++ b/src/nitro/room/object/visualization/room/rasterizer/basic/PlaneRasterizer.ts @@ -0,0 +1,609 @@ +import { Graphics, Point, Texture } from 'pixi.js'; +import { IGraphicAsset } from '../../../../../../../room/object/visualization/utils/IGraphicAsset'; +import { IGraphicAssetCollection } from '../../../../../../../room/object/visualization/utils/IGraphicAssetCollection'; +import { IRoomGeometry } from '../../../../../../../room/utils/IRoomGeometry'; +import { IVector3D } from '../../../../../../../room/utils/IVector3D'; +import { Rasterizer } from '../../../../../../../room/utils/Rasterizer'; +import { RoomGeometry } from '../../../../../../../room/utils/RoomGeometry'; +import { Vector3d } from '../../../../../../../room/utils/Vector3d'; +import { PlaneBitmapData } from '../../utils/PlaneBitmapData'; +import { IPlaneRasterizer } from '../IPlaneRasterizer'; +import { FloorPlane } from './FloorPlane'; +import { Plane } from './Plane'; +import { PlaneMaterial } from './PlaneMaterial'; +import { PlaneMaterialCell } from './PlaneMaterialCell'; +import { PlaneMaterialCellColumn } from './PlaneMaterialCellColumn'; +import { PlaneMaterialCellMatrix } from './PlaneMaterialCellMatrix'; +import { PlaneTexture } from './PlaneTexture'; +import { PlaneVisualizationLayer } from './PlaneVisualizationLayer'; + +export class PlaneRasterizer implements IPlaneRasterizer +{ + protected static DEFAULT: string = 'default'; + + private _assetCollection: IGraphicAssetCollection; + private _materials: Map; + private _textures: Map; + private _planes: Map; + private _geometries: Map; + private _data: any; + + constructor() + { + this._assetCollection = null; + this._textures = new Map(); + this._materials = new Map(); + this._planes = new Map(); + this._geometries = new Map(); + this._data = null; + } + + protected get data(): any + { + return this._data; + } + + protected get _Str_2697(): IGraphicAssetCollection + { + return this._assetCollection; + } + + public initializeDimensions(k: number, _arg_2: number): boolean + { + return true; + } + + public dispose(): void + { + if(this._planes) + { + for(const plane of this._planes.values()) + { + if(!plane) continue; + + plane.dispose(); + } + + this._planes = null; + } + + if(this._materials) + { + this._Str_21781(); + + this._materials = null; + } + + if(this._textures) + { + this._Str_21447(); + + this._textures = null; + } + + if(this._geometries) + { + for(const geometry of this._geometries.values()) + { + if(!geometry) continue; + + geometry.dispose(); + } + + this._geometries = null; + } + + this._data = null; + this._assetCollection = null; + } + + public _Str_3355(): void + { + for(const plane of this._planes.values()) + { + if(!plane) continue; + + plane._Str_3355(); + } + + for(const material of this._materials.values()) + { + if(!material) continue; + + material._Str_3355(); + } + } + + public initialize(data: any): void + { + this._data = data; + } + + public _Str_24005(): void + { + this._Str_21447(); + this._Str_21781(); + this._Str_22054(); + } + + private _Str_21781(): void + { + for(const material of this._materials.values()) + { + if(!material) continue; + + material.dispose(); + } + + this._materials.clear(); + } + + private _Str_21447(): void + { + for(const texture of this._textures.values()) + { + if(!texture) continue; + + texture.dispose(); + } + + this._textures.clear(); + } + + protected _Str_10114(k: string): PlaneTexture + { + return this._textures.get(k); + } + + protected _Str_8547(k: string): PlaneMaterial + { + return this._materials.get(k); + } + + protected _Str_3491(k: string): Plane + { + return this._planes.get(k); + } + + protected _Str_3453(k: string, _arg_2: Plane): boolean + { + if(!_arg_2) return false; + + const existing = this._planes.get(k); + + if(!existing) + { + this._planes.set(k, _arg_2); + + return true; + } + + return false; + } + + public _Str_6703(k: IGraphicAssetCollection): void + { + if(!this._data) return; + + this._assetCollection = k; + + this._Str_22054(); + } + + private _Str_22054(): void + { + if(!this._data) return; + + this._Str_25281(); + + this.initializePlanes(); + } + + private _Str_25281(): void + { + if(this._data.textures && this._data.textures.length) this._Str_24250(this._data.textures, this._Str_2697); + + if(this._data.materials && this._data.materials.length) this._Str_22388(this._data.materials); + } + + protected initializePlanes(): void + { + } + + private _Str_24250(k: any, _arg_2: IGraphicAssetCollection): void + { + if(!k || !_arg_2) return; + + if(k.length) + { + for(const texture of k) + { + if(!texture) continue; + + const id = texture.id; + + if(!this._textures.get(id)) + { + const plane = new PlaneTexture(); + + if(texture.bitmaps && texture.bitmaps.length) + { + for(const bitmap of texture.bitmaps) + { + if(!bitmap) continue; + + const assetName = bitmap.assetName; + + let normalMinX = PlaneTexture._Str_3268; + let normalMaxX = PlaneTexture._Str_3271; + let normalMinY = PlaneTexture._Str_3268; + let normalMaxY = PlaneTexture._Str_3271; + + if(bitmap.normalMinX !== undefined) normalMinX = bitmap.normalMinX; + if(bitmap.normalMaxX !== undefined) normalMaxX = bitmap.normalMaxX; + if(bitmap.normalMinY !== undefined) normalMinY = bitmap.normalMinY; + if(bitmap.normalMaxY !== undefined) normalMaxY = bitmap.normalMaxY; + + const asset = _arg_2.getAsset(assetName); + + if(asset) + { + const texture = asset.texture; + + if(texture) + { + let newTexture: Texture = texture; + + if(asset.flipH) + { + newTexture = Rasterizer._Str_16640(texture); + } + + plane._Str_16790(newTexture, normalMinX, normalMaxX, normalMinY, normalMaxY, assetName); + } + } + } + } + + this._textures.set(id, plane); + } + } + } + } + + private _Str_22388(k: any): void + { + if(!k || !k.length) return; + + for(const material of k) + { + if(!material) continue; + + const id = material.id; + const newMaterial = new PlaneMaterial(); + + if(material.matrices && material.matrices.length) + { + for(const matrix of material.matrices) + { + if(!matrix) continue; + + let repeatMode = matrix.repeatMode; + let align = matrix.align; + const normalMinX = PlaneMaterialCellMatrix._Str_3268; + const normalMaxX = PlaneMaterialCellMatrix._Str_3271; + const normalMinY = PlaneMaterialCellMatrix._Str_3268; + const normalMaxY = PlaneMaterialCellMatrix._Str_3271; + + switch(repeatMode) + { + case 'borders': + repeatMode = PlaneMaterialCellMatrix._Str_6087; + break; + case 'center': + repeatMode = PlaneMaterialCellMatrix._Str_6114; + break; + case 'first': + repeatMode = PlaneMaterialCellMatrix._Str_6187; + break; + case 'last': + repeatMode = PlaneMaterialCellMatrix._Str_6063; + break; + case 'random': + repeatMode = PlaneMaterialCellMatrix._Str_9127; + break; + default: + repeatMode = PlaneMaterialCellMatrix._Str_18632; + break; + } + + switch(align) + { + case 'top': + align = PlaneMaterialCellMatrix.ALIGN_TOP; + break; + case 'bottom': + align = PlaneMaterialCellMatrix._Str_3606; + break; + default: + align = PlaneMaterialCellMatrix._Str_6914; + break; + } + + if(matrix.columns && matrix.columns.length) + { + const cellMatrix = newMaterial._Str_24503(matrix.columns.length, repeatMode, align, normalMinX, normalMaxX, normalMinY, normalMaxY); + + let index = 0; + + while(index < matrix.columns.length) + { + const column = matrix.columns[index]; + + if(column) this._Str_24431(column, cellMatrix, index); + + index++; + } + } + } + } + + this._materials.set(id, newMaterial); + } + } + + private _Str_24431(k: { repeatMode: string, width: number }, _arg_2: PlaneMaterialCellMatrix, _arg_3: number): void + { + if(!k || !_arg_2) return; + + let repeatMode = PlaneMaterialCellColumn._Str_7916; + + const width = k.width; + + const cells = this._Str_25217(k); + + switch(k.repeatMode) + { + case 'borders': + repeatMode = PlaneMaterialCellColumn._Str_6087; + break; + case 'center': + repeatMode = PlaneMaterialCellColumn._Str_6114; + break; + case 'first': + repeatMode = PlaneMaterialCellColumn._Str_6187; + break; + case 'last': + repeatMode = PlaneMaterialCellColumn._Str_6063; + break; + case 'none': + repeatMode = PlaneMaterialCellColumn._Str_9685; + break; + default: + repeatMode = PlaneMaterialCellColumn._Str_7916; + break; + } + + _arg_2._Str_22372(_arg_3, width, cells, repeatMode); + } + + private _Str_25217(k: any): PlaneMaterialCell[] + { + if(!k || !k.cells || !k.cells.length) return null; + + const cells: PlaneMaterialCell[] = []; + + let index = 0; + + while(index < k.cells.length) + { + const cell = k.cells[index]; + + if(cell) + { + const textureId = cell.textureId; + + let assetNames: string[] = null; + let offsetPoints: Point[] = null; + let graphics: IGraphicAsset[] = null; + let limit = 0; + + if(cell.extras && cell.extras.length) + { + const extra = cell.extras[0]; + const types = extra.types; + const offsets = extra.offsets; + + if(types && offsets) + { + if(types.length && offsets.length) + { + const type = types[0]; + const offset = offsets[0]; + + assetNames = this._Str_25465(type); + offsetPoints = this._Str_24448(offset); + limit = offsetPoints.length; + + if(extra.limitMax) limit = extra.limitMax; + } + } + } + + if(assetNames && assetNames.length) + { + graphics = []; + + for(const assetName of assetNames) + { + if(!assetName) continue; + + const asset = this._assetCollection.getAsset(assetName); + + if(!asset) continue; + + graphics.push(asset); + } + } + + const texture = this._Str_10114(textureId); + const newCell = new PlaneMaterialCell(texture, graphics, offsetPoints, limit); + + cells.push(newCell); + } + + index++; + } + + if(!cells || !cells.length) return null; + + return cells; + } + + private _Str_25465(k: any): string[] + { + const assetNames: string[] = []; + + if(k && k.types && k.types.length) + { + let index = 0; + + while(index < k.types.length) + { + const type = k.types[index]; + + const assetName = type.assetName; + + if(assetName) assetNames.push(assetName); + + index++; + } + } + + return assetNames; + } + + private _Str_24448(k: any): Point[] + { + const offsets: Point[] = []; + + if(k && k.offsets && k.offsets.length) + { + let index = 0; + + while(index < k.offsets.length) + { + const offset = k.offsets[index]; + + const x = offset.x; + const y = offset.y; + + offsets.push(new Point(x, y)); + + index++; + } + } + + return offsets; + } + + protected _Str_17204(k: number, _arg_2: number, _arg_3: number): IRoomGeometry + { + _arg_2 = Math.abs(_arg_2); + if(_arg_2 > 90) _arg_2 = 90; + + _arg_3 = Math.abs(_arg_3); + if(_arg_3 > 90) _arg_3 = 90; + + const identifier = `${ k }_${ Math.round(_arg_2) }_${ Math.round(_arg_3) }`; + + let geometry = this._geometries.get(identifier); + + if(geometry) return geometry; + + geometry = new RoomGeometry(k, new Vector3d(_arg_2, _arg_3), new Vector3d(-10, 0, 0)); + + this._geometries.set(identifier, geometry); + + return geometry; + } + + protected _Str_9137(k: Plane, _arg_2: any): void + { + if(!k || !_arg_2) return; + + if(_arg_2 && _arg_2.length) + { + for(const visualization of _arg_2) + { + if(!visualization) continue; + + const size = visualization.size; + + let horizontalAngle = FloorPlane._Str_5433; + let verticalAngle = FloorPlane._Str_5509; + + if(visualization.horizontalAngle) horizontalAngle = visualization.horizontalAngle; + if(visualization.verticalAngle) verticalAngle = visualization.verticalAngle; + + const layers = visualization.layers; + + const planeVisualization = k._Str_20305(size, ((layers && layers.length) || 0), this._Str_17204(size, horizontalAngle, verticalAngle)); + + if(planeVisualization && (layers && layers.length)) + { + let layerId = 0; + + while(layerId < layers.length) + { + const layer = layers[layerId]; + + if(layer) + { + let material: PlaneMaterial = null; + let align: number = PlaneVisualizationLayer._Str_6914; + let color: number = FloorPlane._Str_2531; + let offset: number = PlaneVisualizationLayer._Str_1934; + + if(layer.materialId) material = this._Str_8547(layer.materialId); + + if(layer.color) color = layer.color; + + if(layer.offset) offset = layer.offset; + + if(layer.align) + { + if(layer.align === 'bottom') align = PlaneVisualizationLayer._Str_3606; + + else if(layer.align == 'top') align = PlaneVisualizationLayer.ALIGN_TOP; + } + + planeVisualization._Str_21464(layerId, material, color, align, offset); + } + + layerId++; + } + } + } + } + } + + public render(k: Graphics, _arg_2: string, _arg_3: number, _arg_4: number, _arg_5: number, _arg_6: IVector3D, _arg_7: boolean, _arg_8: number =0, _arg_9: number = 0, _arg_10: number = 0, _arg_11: number = 0, _arg_12: number = 0): PlaneBitmapData + { + return null; + } + + public getTextureIdentifier(k: number, _arg_2: IVector3D): string + { + return k.toString(); + } + + public _Str_8988(k: string): PlaneVisualizationLayer[] + { + let planes = this._Str_3491(k); + + if(!planes) planes = this._Str_3491(PlaneRasterizer.DEFAULT); + + return planes._Str_8988(); + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/room/rasterizer/basic/PlaneTexture.ts b/src/nitro/room/object/visualization/room/rasterizer/basic/PlaneTexture.ts new file mode 100644 index 00000000..0e7a38a6 --- /dev/null +++ b/src/nitro/room/object/visualization/room/rasterizer/basic/PlaneTexture.ts @@ -0,0 +1,66 @@ +import { Texture } from 'pixi.js'; +import { IVector3D } from '../../../../../../../room/utils/IVector3D'; +import { PlaneTextureBitmap } from './PlaneTextureBitmap'; + +export class PlaneTexture +{ + public static _Str_3268: number = -1; + public static _Str_3271: number = 1; + + private _bitmaps: PlaneTextureBitmap[]; + + constructor() + { + this._bitmaps = []; + } + + public dispose(): void + { + if(this._bitmaps) + { + for(const bitmap of this._bitmaps) + { + if(!bitmap) continue; + + bitmap.dispose(); + } + + this._bitmaps = null; + } + } + + public _Str_16790(k: Texture, _arg_2: number = -1, _arg_3: number = 1, _arg_4: number = -1, _arg_5: number = 1, _arg_6: string = null): void + { + this._bitmaps.push(new PlaneTextureBitmap(k, _arg_2, _arg_3, _arg_4, _arg_5, _arg_6)); + } + + public _Str_4913(k: IVector3D): Texture + { + const _local_2 = this._Str_21702(k); + + if(!_local_2) return null; + + return _local_2.bitmap; + } + + public _Str_21702(k: IVector3D): PlaneTextureBitmap + { + if(!k) return null; + + for(const bitmap of this._bitmaps) + { + if(!bitmap) continue; + + if((((k.x >= bitmap.normalMinX) && (k.x <= bitmap.normalMaxX)) && (k.y >= bitmap.normalMinY)) && (k.y <= bitmap.normalMaxY)) return bitmap; + } + + return null; + } + + public _Str_2125(k: IVector3D): string + { + const _local_2 = this._Str_21702(k); + + return (!_local_2) ? null : _local_2.assetName; + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/room/rasterizer/basic/PlaneTextureBitmap.ts b/src/nitro/room/object/visualization/room/rasterizer/basic/PlaneTextureBitmap.ts new file mode 100644 index 00000000..ca0be442 --- /dev/null +++ b/src/nitro/room/object/visualization/room/rasterizer/basic/PlaneTextureBitmap.ts @@ -0,0 +1,59 @@ +import { Texture } from 'pixi.js'; + +export class PlaneTextureBitmap +{ + public static _Str_3268: number = -1; + public static _Str_3271: number = 1; + + private _bitmap: Texture; + private _normalMinX: number; + private _normalMaxX: number; + private _normalMinY: number; + private _normalMaxY: number; + private _assetName: string; + + constructor(k: Texture, _arg_2: number = -1, _arg_3: number = 1, _arg_4: number = -1, _arg_5: number = 1, _arg_6: string = null) + { + this._normalMinX = _arg_2; + this._normalMaxX = _arg_3; + this._normalMinY = _arg_4; + this._normalMaxY = _arg_5; + this._assetName = _arg_6; + this._bitmap = k; + } + + public get bitmap(): Texture + { + return this._bitmap; + } + + public get normalMinX(): number + { + return this._normalMinX; + } + + public get normalMaxX(): number + { + return this._normalMaxX; + } + + public get normalMinY(): number + { + return this._normalMinY; + } + + public get normalMaxY(): number + { + return this._normalMaxY; + } + + public get assetName(): string + { + return this._assetName; + } + + public dispose(): void + { + this._bitmap = null; + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/room/rasterizer/basic/PlaneVisualization.ts b/src/nitro/room/object/visualization/room/rasterizer/basic/PlaneVisualization.ts new file mode 100644 index 00000000..44caaa5a --- /dev/null +++ b/src/nitro/room/object/visualization/room/rasterizer/basic/PlaneVisualization.ts @@ -0,0 +1,240 @@ +import { Graphics, Rectangle } from 'pixi.js'; +import { IDisposable } from '../../../../../../../core/common/disposable/IDisposable'; +import { IGraphicAssetCollection } from '../../../../../../../room/object/visualization/utils/IGraphicAssetCollection'; +import { IRoomGeometry } from '../../../../../../../room/utils/IRoomGeometry'; +import { IVector3D } from '../../../../../../../room/utils/IVector3D'; +import { TextureUtils } from '../../../../../../../room/utils/TextureUtils'; +import { Vector3d } from '../../../../../../../room/utils/Vector3d'; +import { PlaneVisualizationAnimationLayer } from '../animated/PlaneVisualizationAnimationLayer'; +import { PlaneMaterial } from './PlaneMaterial'; +import { PlaneVisualizationLayer } from './PlaneVisualizationLayer'; + +export class PlaneVisualization +{ + private _layers: IDisposable[]; + private _geometry: IRoomGeometry; + private _cachedBitmapData: Graphics; + private _cachedBitmapNormal: Vector3d; + private _isCached: boolean; + private _hasAnimationLayers: boolean; + + constructor(k: number, _arg_2: number, _arg_3: IRoomGeometry) + { + this._layers = []; + this._geometry = _arg_3; + this._cachedBitmapData = null; + this._cachedBitmapNormal = new Vector3d(); + this._isCached = false; + this._hasAnimationLayers = false; + + if(_arg_2 < 0) _arg_2 = 0; + + let index = 0; + + while(index < _arg_2) + { + this._layers.push(null); + + index++; + } + } + + public get geometry(): IRoomGeometry + { + return this._geometry; + } + + public get _Str_20530(): boolean + { + return this._hasAnimationLayers; + } + + public dispose(): void + { + if(this._layers && this._layers.length) + { + for(const layer of this._layers) + { + if(!layer) continue; + + layer.dispose(); + } + + this._layers = null; + } + + this._geometry = null; + + if(this._cachedBitmapData) + { + this._cachedBitmapData.destroy(); + + this._cachedBitmapData = null; + } + + if(this._cachedBitmapNormal) this._cachedBitmapNormal = null; + } + + public _Str_3355(): void + { + if(!this._isCached) return; + + if(this._cachedBitmapData) + { + this._cachedBitmapData.destroy(); + + this._cachedBitmapData = null; + } + + if(this._cachedBitmapNormal) + { + this._cachedBitmapNormal.assign(new Vector3d()); + } + + if(this._layers && this._layers.length) + { + for(const layer of this._layers) + { + if(!layer) continue; + + const planeLayer = layer as PlaneVisualizationLayer; + + planeLayer._Str_3355(); + } + } + + this._isCached = false; + } + + public _Str_21464(k: number, _arg_2: PlaneMaterial, _arg_3: number, _arg_4: number, _arg_5: number = 0): boolean + { + if((k < 0) || (k > this._layers.length)) return false; + + let layer = this._layers[k]; + + if(layer) layer.dispose(); + + layer = new PlaneVisualizationLayer(_arg_2, _arg_3, _arg_4, _arg_5); + + this._layers[k] = layer; + + return true; + } + + public _Str_23489(k: number, _arg_2: any, _arg_3: IGraphicAssetCollection): boolean + { + if((k < 0) || (k > this._layers.length)) return false; + + let layer = this._layers[k] as IDisposable; + + if(layer) layer.dispose(); + + layer = new PlaneVisualizationAnimationLayer(_arg_2, _arg_3); + + this._layers[k] = layer; + this._hasAnimationLayers = true; + + return true; + } + + public _Str_8988(): PlaneVisualizationLayer[] + { + return this._layers as PlaneVisualizationLayer[]; + } + + public render(canvas: Graphics, width: number, height: number, normal: IVector3D, useTexture: boolean, offsetX: number = 0, offsetY: number = 0, maxX: number = 0, maxY: number = 0, dimensionX: number = 0, dimensionY: number = 0, timeSinceStartMs: number = 0): Graphics + { + if(width < 1) width = 1; + + if(height < 1) height = 1; + + if((!canvas || (canvas.width !== width)) || (canvas.height !== height)) canvas = null; + + if(this._cachedBitmapData) + { + if(((this._cachedBitmapData.width === width) && (this._cachedBitmapData.height === height)) && (Vector3d.isEqual(this._cachedBitmapNormal, normal))) + { + if(!this._Str_20530) + { + if(canvas) + { + const texture = TextureUtils.generateTexture(this._cachedBitmapData, new Rectangle(0, 0, width, height)); + + if(texture) + { + canvas + .beginTextureFill({ texture }) + .drawRect(0, 0, texture.width, texture.height) + .endFill(); + + return canvas; + } + } + + return this._cachedBitmapData; + } + } + else + { + this._cachedBitmapData.destroy(); + + this._cachedBitmapData = null; + } + } + + this._isCached = true; + + if(!this._cachedBitmapData) + { + const graphic = new Graphics() + .beginFill(0xFFFFFF) + .drawRect(0, 0, width, height) + .endFill(); + + this._cachedBitmapData = graphic; + } + else + { + this._cachedBitmapData + .beginFill(0xFFFFFF) + .drawRect(0, 0, width, height) + .endFill(); + } + + if(!canvas) canvas = this._cachedBitmapData; + + this._cachedBitmapNormal.assign(normal); + + if(this._layers && this._layers.length) + { + for(const layer of this._layers) + { + if(!layer) continue; + + if(layer instanceof PlaneVisualizationLayer) + { + layer.render(canvas, width, height, normal, useTexture, offsetX, offsetY); + } + + else if(layer instanceof PlaneVisualizationAnimationLayer) + { + layer.render(canvas, width, height, normal, offsetX, offsetY, maxX, maxY, dimensionX, dimensionY, timeSinceStartMs); + } + } + } + + if(canvas && (canvas !== this._cachedBitmapData)) + { + const texture = TextureUtils.generateTexture(canvas, new Rectangle(0, 0, canvas.width, canvas.height)); + + this._cachedBitmapData + .beginTextureFill({ texture }) + .drawRect(0, 0, canvas.width, canvas.height) + .endFill(); + + return canvas; + } + + return this._cachedBitmapData; + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/room/rasterizer/basic/PlaneVisualizationLayer.ts b/src/nitro/room/object/visualization/room/rasterizer/basic/PlaneVisualizationLayer.ts new file mode 100644 index 00000000..7ebe4650 --- /dev/null +++ b/src/nitro/room/object/visualization/room/rasterizer/basic/PlaneVisualizationLayer.ts @@ -0,0 +1,147 @@ +import { Graphics, Rectangle } from 'pixi.js'; +import { IVector3D } from '../../../../../../../room/utils/IVector3D'; +import { TextureUtils } from '../../../../../../../room/utils/TextureUtils'; +import { RoomVisualization } from '../../RoomVisualization'; +import { PlaneMaterial } from './PlaneMaterial'; + +export class PlaneVisualizationLayer +{ + public static _Str_1934: number = 0; + public static ALIGN_TOP: number = 1; + public static _Str_3606: number = 2; + public static _Str_6914: number = PlaneVisualizationLayer.ALIGN_TOP; + + private _material: PlaneMaterial; + private _color: number; + private _offset: number; + private _align: number; + private _bitmapData: Graphics; + private _isDisposed: boolean; + + constructor(k: PlaneMaterial, _arg_2: number, _arg_3: number, _arg_4: number = 0) + { + this._material = k; + this._offset = _arg_4; + this._align = _arg_3; + this._color = _arg_2; + this._bitmapData = null; + this._isDisposed = false; + } + + public get offset(): number + { + return this._offset; + } + + public get align(): number + { + return this._align; + } + + public get disposed(): boolean + { + return this._isDisposed; + } + + public dispose(): void + { + this._isDisposed = true; + this._material = null; + + this._Str_3355(); + } + + public _Str_3355(): void + { + if(this._bitmapData) + { + this._bitmapData.destroy(); + + this._bitmapData = null; + } + } + + public render(canvas: Graphics, width: number, height: number, normal: IVector3D, useTexture: boolean, offsetX: number, offsetY: number): Graphics + { + if(!canvas || (canvas.width !== width) || (canvas.height !== height)) canvas = null; + + let bitmapData: Graphics = null; + + if(this._material) + { + bitmapData = this._material.render(null, width, height, normal, useTexture, offsetX, (offsetY + this.offset), (this.align === PlaneVisualizationLayer.ALIGN_TOP)); + + if(bitmapData && (bitmapData !== canvas)) + { + if(this._bitmapData) this._bitmapData.destroy(); + + this._bitmapData = bitmapData.clone(); + + bitmapData = this._bitmapData; + } + } + else + { + if(!canvas) + { + if(this._bitmapData && (this._bitmapData.width === width) && (this._bitmapData.height === height)) return this._bitmapData; + + if(this._bitmapData) this._bitmapData.destroy(); + + const graphic = new Graphics() + .beginFill(0xFFFFFF) + .drawRect(0, 0, width, height) + .endFill(); + + this._bitmapData = graphic; + + bitmapData = this._bitmapData; + } + else + { + canvas + .beginFill(0xFFFFFF) + .drawRect(0, 0, width, height) + .endFill(); + + bitmapData = canvas; + } + } + + if(bitmapData) + { + bitmapData.tint = this._color; + + if(canvas && (bitmapData !== canvas)) + { + let texture = RoomVisualization.getTextureCache(bitmapData); + + if(!texture) + { + texture = TextureUtils.generateTexture(bitmapData, new Rectangle(0, 0, width, height)); + + RoomVisualization.addTextureCache(bitmapData, texture); + } + + canvas + .beginTextureFill({ texture }) + .drawRect(0, 0, width, height) + .endFill(); + + bitmapData = canvas; + } + } + + return bitmapData; + } + + public _Str_8547(): PlaneMaterial + { + return this._material; + } + + public _Str_751(): number + { + return this._color; + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/room/rasterizer/basic/WallPlane.ts b/src/nitro/room/object/visualization/room/rasterizer/basic/WallPlane.ts new file mode 100644 index 00000000..dd6e13c3 --- /dev/null +++ b/src/nitro/room/object/visualization/room/rasterizer/basic/WallPlane.ts @@ -0,0 +1,30 @@ +import { Graphics } from 'pixi.js'; +import { IVector3D } from '../../../../../../../room/utils/IVector3D'; +import { Vector3d } from '../../../../../../../room/utils/Vector3d'; +import { Plane } from './Plane'; + +export class WallPlane extends Plane +{ + public static _Str_2531: number = 0xFFFFFF; + public static _Str_5433: number = 45; + public static _Str_5509: number = 30; + + public render(k: Graphics, _arg_2: number, _arg_3: number, size: number, _arg_5: IVector3D, _arg_6: boolean): Graphics + { + const visualization = this._Str_6009(size); + + if(!visualization || !visualization.geometry) return null; + + const _local_8 = visualization.geometry.getScreenPoint(new Vector3d(0, 0, 0)); + const _local_9 = visualization.geometry.getScreenPoint(new Vector3d(0, 0, (_arg_3 / visualization.geometry.scale))); + const _local_10 = visualization.geometry.getScreenPoint(new Vector3d(0, (_arg_2 / visualization.geometry.scale), 0)); + + if(_local_8 && _local_9 && _local_10) + { + _arg_2 = Math.round(Math.abs((_local_8.x - _local_10.x))); + _arg_3 = Math.round(Math.abs((_local_8.y - _local_9.y))); + } + + return visualization.render(k, _arg_2, _arg_3, _arg_5, _arg_6); + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/room/rasterizer/basic/WallRasterizer.ts b/src/nitro/room/object/visualization/room/rasterizer/basic/WallRasterizer.ts new file mode 100644 index 00000000..38c0e5a5 --- /dev/null +++ b/src/nitro/room/object/visualization/room/rasterizer/basic/WallRasterizer.ts @@ -0,0 +1,76 @@ +import { Graphics } from 'pixi.js'; +import { IVector3D } from '../../../../../../../room/utils/IVector3D'; +import { PlaneBitmapData } from '../../utils/PlaneBitmapData'; +import { PlaneRasterizer } from './PlaneRasterizer'; +import { WallPlane } from './WallPlane'; + +export class WallRasterizer extends PlaneRasterizer +{ + protected initializePlanes(): void + { + if(!this.data) return; + + const walls = this.data.walls; + + if(walls && walls.length) this._Str_24495(walls); + } + + private _Str_24495(k: any): void + { + if(!k) return; + + for(const wallIndex in k) + { + const wall = k[wallIndex]; + + if(!wall) continue; + + const id = wall.id; + const visualization = wall.visualizations; + const plane = new WallPlane(); + + this._Str_9137(plane, visualization); + + if(!this._Str_3453(id, plane)) plane.dispose(); + } + } + + public render(canvas: Graphics, id: string, width: number, height: number, scale: number, normal: IVector3D, useTexture: boolean, offsetX: number = 0, offsetY: number = 0, maxX: number = 0, maxY: number = 0, timeSinceStartMs: number = 0): PlaneBitmapData + { + let plane = this._Str_3491(id) as WallPlane; + + if(!plane) plane = this._Str_3491(PlaneRasterizer.DEFAULT) as WallPlane; + + if(!plane) return null; + + if(canvas) + { + const rectangle = canvas.getBounds(); + + canvas.clear(); + + canvas.drawRect(rectangle.x, rectangle.y, rectangle.width, rectangle.height); + } + + let graphic = plane.render(canvas, width, height, scale, normal, useTexture); + + if(graphic && (graphic !== canvas)) + { + graphic = graphic.clone(); + + if(!graphic) return null; + } + + return new PlaneBitmapData(graphic, -1); + } + + public getTextureIdentifier(k: number, _arg_2: IVector3D): string + { + if(_arg_2) + { + return `${ k }_${ _arg_2.x }_${ _arg_2.y }_${ _arg_2.z }`; + } + + return super.getTextureIdentifier(k, _arg_2); + } +} diff --git a/src/nitro/room/object/visualization/room/utils/PlaneBitmapData.ts b/src/nitro/room/object/visualization/room/utils/PlaneBitmapData.ts new file mode 100644 index 00000000..c9af1ab3 --- /dev/null +++ b/src/nitro/room/object/visualization/room/utils/PlaneBitmapData.ts @@ -0,0 +1,28 @@ +import { Graphics } from 'pixi.js'; + +export class PlaneBitmapData +{ + private _bitmap: Graphics; + private _timeStamp: number; + + constructor(k: Graphics, _arg_2: number) + { + this._bitmap = k; + this._timeStamp = _arg_2; + } + + public dispose(): void + { + this._bitmap = null; + } + + public get bitmap(): Graphics + { + return this._bitmap; + } + + public get timeStamp(): number + { + return this._timeStamp; + } +} \ No newline at end of file diff --git a/src/nitro/room/object/visualization/room/utils/Randomizer.ts b/src/nitro/room/object/visualization/room/utils/Randomizer.ts new file mode 100644 index 00000000..7df59937 --- /dev/null +++ b/src/nitro/room/object/visualization/room/utils/Randomizer.ts @@ -0,0 +1,126 @@ +export class Randomizer +{ + public static _Str_21045: number = 1; + public static _Str_20078: number = 16777216; + + private static _Str_3699:Randomizer = null; + + private _Str_16737: number = 1; + private _Str_16979: number = 16777216; + private _Str_25697: number = 69069; + private _Str_23320: number = 5; + + public static _Str_17384(k: number = 1): void + { + if(!Randomizer._Str_3699) Randomizer._Str_3699 = new Randomizer(); + + Randomizer._Str_3699._Str_15634 = k; + } + + public static _Str_26085(k: number = 16777216): void + { + if(!Randomizer._Str_3699) Randomizer._Str_3699 = new Randomizer(); + + Randomizer._Str_3699._Str_25321 = k; + } + + public static _Str_1612(k: number, _arg_2: number, _arg_3: number): number[] + { + if(!Randomizer._Str_3699) Randomizer._Str_3699 = new Randomizer(); + + return Randomizer._Str_3699._Str_24535(k, _arg_2, _arg_3); + } + + public static _Str_23572(k: number, _arg_2: number): number[] + { + if(!Randomizer._Str_3699) Randomizer._Str_3699 = new Randomizer(); + + return Randomizer._Str_3699._Str_24231(k, _arg_2); + } + + public set _Str_15634(k: number) + { + this._Str_16737 = k; + } + + public set _Str_25321(k: number) + { + if(k < 1) k = 1; + + this._Str_16979 = k; + } + + public dispose(): void + { + } + + public _Str_24535(k: number, _arg_2: number, _arg_3: number): number[] + { + const _local_4: number[] = []; + + let _local_5 = 0; + + while(_local_5 < k) + { + _local_4.push(this._Str_19361(_arg_2, (_arg_3 - _arg_2))); + _local_5++; + } + + return _local_4; + } + + public _Str_24231(k: number, _arg_2: number): number[] + { + if(((k > _arg_2) || (_arg_2 > 1000))) return null; + + const _local_3: number[] = []; + + let _local_4 = 0; + + while(_local_4 <= _arg_2) + { + _local_3.push(_local_4); + _local_4++; + } + + const _local_5: number[] = []; + + let _local_6 = 0; + + while(_local_6 < k) + { + const _local_7 = this._Str_19361(0, (_local_3.length - 1)); + + _local_5.push(_local_3[_local_7]); + _local_3.splice(_local_7, 1); + + _local_6++; + } + + return _local_5; + } + + private _Str_24980(): number + { + let k: number = ((this._Str_25697 * this._Str_16737) + this._Str_23320); + + if(k < 0) k = -(k); + + k = (k % this._Str_16979); + + this._Str_16737 = k; + + return k; + } + + private _Str_19361(k: number, _arg_2: number): number + { + let _local_3: number = this._Str_24980(); + + if(_arg_2 < 1) return k; + + _local_3 = (k + ((_local_3 / this._Str_16979) * _arg_2)); + + return _local_3; + } +} \ No newline at end of file diff --git a/src/nitro/room/preview/RoomPreviewer.ts b/src/nitro/room/preview/RoomPreviewer.ts new file mode 100644 index 00000000..24bea90c --- /dev/null +++ b/src/nitro/room/preview/RoomPreviewer.ts @@ -0,0 +1,853 @@ +import { Container, DisplayObject, Point, Rectangle, RenderTexture, Sprite, Texture } from 'pixi.js'; +import { IRoomObjectController } from '../../../room/object/IRoomObjectController'; +import { IRoomRenderingCanvas } from '../../../room/renderer/IRoomRenderingCanvas'; +import { IVector3D } from '../../../room/utils/IVector3D'; +import { RoomId } from '../../../room/utils/RoomId'; +import { Vector3d } from '../../../room/utils/Vector3d'; +import { RoomDoorParser } from '../../communication/messages/parser/room/mapping/RoomDoorParser'; +import { RoomModelParser } from '../../communication/messages/parser/room/mapping/RoomModelParser'; +import { Nitro } from '../../Nitro'; +import { RoomEngineEvent } from '../events/RoomEngineEvent'; +import { RoomEngineObjectEvent } from '../events/RoomEngineObjectEvent'; +import { IGetImageListener } from '../IGetImageListener'; +import { ImageResult } from '../ImageResult'; +import { IRoomCreator } from '../IRoomCreator'; +import { IRoomEngine } from '../IRoomEngine'; +import { ObjectRoomMapUpdateMessage } from '../messages/ObjectRoomMapUpdateMessage'; +import { IObjectData } from '../object/data/IObjectData'; +import { LegacyDataType } from '../object/data/type/LegacyDataType'; +import { RoomObjectCategory } from '../object/RoomObjectCategory'; +import { RoomObjectUserType } from '../object/RoomObjectUserType'; +import { RoomObjectVariable } from '../object/RoomObjectVariable'; +import { RoomPlaneParser } from '../object/RoomPlaneParser'; +import { RoomEngine } from '../RoomEngine'; +import { LegacyWallGeometry } from '../utils/LegacyWallGeometry'; + +export class RoomPreviewer +{ + public static SCALE_NORMAL: number = 64; + public static SCALE_SMALL: number = 32; + public static PREVIEW_COUNTER: number = 0; + public static PREVIEW_CANVAS_ID: number = 1; + public static PREVIEW_OBJECT_ID: number = 1; + public static PREVIEW_OBJECT_LOCATION_X: number = 2; + public static PREVIEW_OBJECT_LOCATION_Y: number = 2; + + private static ALLOWED_IMAGE_CUT: number = 0.25; + private static AUTOMATIC_STATE_CHANGE_INTERVAL: number = 2500; + private static ZOOM_ENABLED: boolean = true; + + private _roomEngine: IRoomEngine; + private _planeParser: RoomPlaneParser; + private _previewRoomId: number = 1; + private _currentPreviewObjectType: number = 0; + private _currentPreviewObjectCategory: number = 0; + private _currentPreviewObjectData: string = ''; + private _currentPreviewRectangle: Rectangle = null; + private _currentPreviewCanvasWidth: number = 0; + private _currentPreviewCanvasHeight: number = 0; + private _currentPreviewScale: number = 64; + private _currentPreviewNeedsZoomOut: boolean; + private _automaticStateChange: boolean; + private _previousAutomaticStateChangeTime: number; + private _addViewOffset: Point; + private _backgroundColor: number = 305148561; + private _disableUpdate: boolean = false; + + constructor(roomEngine: IRoomEngine, roomId: number = 1) + { + this._roomEngine = roomEngine; + this._planeParser = new RoomPlaneParser(); + this._previewRoomId = RoomId.makeRoomPreviewerId(roomId); + this._addViewOffset = new Point(0, 0); + + this.onRoomObjectAdded = this.onRoomObjectAdded.bind(this); + this.onRoomInitializedonRoomInitialized = this.onRoomInitializedonRoomInitialized.bind(this); + + if(this.isRoomEngineReady && this._roomEngine.events) + { + this._roomEngine.events.addEventListener(RoomEngineObjectEvent.ADDED, this.onRoomObjectAdded); + this._roomEngine.events.addEventListener(RoomEngineObjectEvent.CONTENT_UPDATED, this.onRoomObjectAdded); + this._roomEngine.events.addEventListener(RoomEngineEvent.INITIALIZED, this.onRoomInitializedonRoomInitialized); + } + + this.createRoomForPreview(); + } + + public dispose(): void + { + this.reset(true); + + if(this.isRoomEngineReady && this._roomEngine.events) + { + this._roomEngine.events.removeEventListener(RoomEngineObjectEvent.ADDED, this.onRoomObjectAdded); + this._roomEngine.events.removeEventListener(RoomEngineObjectEvent.CONTENT_UPDATED, this.onRoomObjectAdded); + this._roomEngine.events.removeEventListener(RoomEngineEvent.INITIALIZED, this.onRoomInitializedonRoomInitialized); + } + + if(this._planeParser) + { + this._planeParser.dispose(); + + this._planeParser = null; + } + } + + private createRoomForPreview(): void + { + if(this.isRoomEngineReady) + { + const size = 7; + + const planeParser = new RoomPlaneParser(); + + planeParser.initializeTileMap((size + 2), (size + 2)); + + let y = 1; + + while(y < (1 + size)) + { + let x = 1; + + while(x < (1 + size)) + { + planeParser.setTileHeight(x, y, 0); + + x++; + } + + y++; + } + + planeParser.initializeFromTileData(); + + this._roomEngine.createRoomInstance(this._previewRoomId, planeParser.getMapData()); + + planeParser.dispose(); + } + } + + public reset(k: boolean): void + { + if(this.isRoomEngineReady) + { + this._roomEngine.removeRoomObjectFloor(this._previewRoomId, RoomPreviewer.PREVIEW_OBJECT_ID); + this._roomEngine.removeRoomObjectWall(this._previewRoomId, RoomPreviewer.PREVIEW_OBJECT_ID); + this._roomEngine.removeRoomObjectUser(this._previewRoomId, RoomPreviewer.PREVIEW_OBJECT_ID); + + if(!k) this.updatePreviewRoomView(); + } + + this._currentPreviewObjectCategory = RoomObjectCategory.MINIMUM; + } + + public updatePreviewModel(model: string, wallHeight: number, scale: boolean = true): void + { + const parser = new RoomModelParser(); + + parser.flush(); + parser.parseModel(model, wallHeight, scale); + + const wallGeometry = ( this._roomEngine as IRoomCreator).getLegacyWallGeometry(this._previewRoomId); + + if(!wallGeometry) return; + + this._planeParser.reset(); + + const width = parser.width; + const height = parser.height; + + this._planeParser.initializeTileMap(width, height); + + const entryTile: RoomDoorParser = null; + + let doorX = -1; + let doorY = -1; + let doorZ = 0; + let doorDirection = 0; + + let y = 0; + + while(y < height) + { + let x = 0; + + while(x < width) + { + const tileHeight = parser.getHeight(x, y); + + if(((((y > 0) && (y < (height - 1))) || ((x > 0) && (x < (width - 1)))) && (!(tileHeight == RoomPlaneParser.TILE_BLOCKED))) && ((entryTile == null) || ((x == entryTile.x) && (y == entryTile.y)))) + { + if(((parser.getHeight(x, (y - 1)) == RoomPlaneParser.TILE_BLOCKED) && (parser.getHeight((x - 1), y) == RoomPlaneParser.TILE_BLOCKED)) && (parser.getHeight(x, (y + 1)) == RoomPlaneParser.TILE_BLOCKED)) + { + doorX = (x + 0.5); + doorY = y; + doorZ = tileHeight; + doorDirection = 90; + } + + if(((parser.getHeight(x, (y - 1)) == RoomPlaneParser.TILE_BLOCKED) && (parser.getHeight((x - 1), y) == RoomPlaneParser.TILE_BLOCKED)) && (parser.getHeight((x + 1), y) == RoomPlaneParser.TILE_BLOCKED)) + { + doorX = x; + doorY = (y + 0.5); + doorZ = tileHeight; + doorDirection = 180; + } + } + + this._planeParser.setTileHeight(x, y, tileHeight); + + x++; + } + + y++; + } + + this._planeParser.setTileHeight(Math.floor(doorX), Math.floor(doorY), doorZ); + this._planeParser.initializeFromTileData(parser.wallHeight); + this._planeParser.setTileHeight(Math.floor(doorX), Math.floor(doorY), (doorZ + this._planeParser.wallHeight)); + + wallGeometry.scale = LegacyWallGeometry.DEFAULT_SCALE; + wallGeometry.initialize(width, height, this._planeParser.floorHeight); + + let heightIterator = (parser.height - 1); + + while(heightIterator >= 0) + { + let widthIterator = (parser.width - 1); + + while(widthIterator >= 0) + { + wallGeometry.setHeight(widthIterator, heightIterator, this._planeParser.getTileHeight(widthIterator, heightIterator)); + widthIterator--; + } + + heightIterator--; + } + + const roomMap = this._planeParser.getMapData(); + + roomMap.doors.push({ + x: doorX, + y: doorY, + z: doorZ, + dir: doorDirection + }); + + const roomObject = this.getRoomPreviewOwnRoomObject(); + + if(roomObject) roomObject.processUpdateMessage(new ObjectRoomMapUpdateMessage(roomMap)); + } + + public addFurnitureIntoRoom(classId: number, direction: IVector3D, objectData: IObjectData = null, extra: string = null): number + { + if(!objectData) objectData = new LegacyDataType(); + + if(this.isRoomEngineReady) + { + if((this._currentPreviewObjectCategory === RoomObjectCategory.FLOOR) && (this._currentPreviewObjectType === classId)) return RoomPreviewer.PREVIEW_OBJECT_ID; + + this.reset(false); + + this._currentPreviewObjectType = classId; + this._currentPreviewObjectCategory = RoomObjectCategory.FLOOR; + this._currentPreviewObjectData = ''; + + if(this._roomEngine.addFurnitureFloor(this._previewRoomId, RoomPreviewer.PREVIEW_OBJECT_ID, classId, new Vector3d(RoomPreviewer.PREVIEW_OBJECT_LOCATION_X, RoomPreviewer.PREVIEW_OBJECT_LOCATION_Y, 0), direction, 0, objectData, NaN, -1, 0, -1, '', true, false)) + { + this._previousAutomaticStateChangeTime = Nitro.instance.time; + this._automaticStateChange = true; + + const roomObject = this._roomEngine.getRoomObject(this._previewRoomId, RoomPreviewer.PREVIEW_OBJECT_ID, this._currentPreviewObjectCategory); + + if(roomObject && extra) roomObject.model.setValue(RoomObjectVariable.FURNITURE_EXTRAS, extra); + + this.updatePreviewRoomView(); + + return RoomPreviewer.PREVIEW_OBJECT_ID; + } + } + + return -1; + } + + public addWallItemIntoRoom(classId: number, direction: IVector3D, objectData: string): number + { + if(this.isRoomEngineReady) + { + if((this._currentPreviewObjectCategory === RoomObjectCategory.WALL) && (this._currentPreviewObjectType === classId) && (this._currentPreviewObjectData === objectData)) return RoomPreviewer.PREVIEW_OBJECT_ID; + + this.reset(false); + + this._currentPreviewObjectType = classId; + this._currentPreviewObjectCategory = RoomObjectCategory.WALL; + this._currentPreviewObjectData = objectData; + + if(this._roomEngine.addFurnitureWall(this._previewRoomId, RoomPreviewer.PREVIEW_OBJECT_ID, classId, new Vector3d(0.5, 2.3, 1.8), direction, 0, objectData, 0, 0, -1, '', false)) + { + this._previousAutomaticStateChangeTime = Nitro.instance.time; + this._automaticStateChange = true; + + this.updatePreviewRoomView(); + + return RoomPreviewer.PREVIEW_OBJECT_ID; + } + } + + return -1; + } + + public addAvatarIntoRoom(figure: string, effect: number): number + { + if(this.isRoomEngineReady) + { + this.reset(false); + + this._currentPreviewObjectType = 1; + this._currentPreviewObjectCategory = RoomObjectCategory.UNIT; + this._currentPreviewObjectData = figure; + + if(this._roomEngine.addRoomObjectUser(this._previewRoomId, RoomPreviewer.PREVIEW_OBJECT_ID, new Vector3d(RoomPreviewer.PREVIEW_OBJECT_LOCATION_X, RoomPreviewer.PREVIEW_OBJECT_LOCATION_Y, 0), new Vector3d(90, 0, 0), 135, RoomObjectUserType.getTypeNumber(RoomObjectUserType.USER), figure)) + { + this._previousAutomaticStateChangeTime = Nitro.instance.time; + this._automaticStateChange = true; + + this.updateUserGesture(1); + this.updateUserEffect(effect); + this.updateUserPosture('std'); + } + + this.updatePreviewRoomView(); + + return RoomPreviewer.PREVIEW_OBJECT_ID; + } + + return -1; + } + + public addPetIntoRoom(figure: string): number + { + if(this.isRoomEngineReady) + { + this.reset(false); + + this._currentPreviewObjectType = 1; + this._currentPreviewObjectCategory = RoomObjectCategory.UNIT; + this._currentPreviewObjectData = figure; + + if(this._roomEngine.addRoomObjectUser(this._previewRoomId, RoomPreviewer.PREVIEW_OBJECT_ID, new Vector3d(RoomPreviewer.PREVIEW_OBJECT_LOCATION_X, RoomPreviewer.PREVIEW_OBJECT_LOCATION_Y, 0), new Vector3d(90, 0, 0), 90, RoomObjectUserType.getTypeNumber(RoomObjectUserType.PET), figure)) + { + this._previousAutomaticStateChangeTime = Nitro.instance.time; + this._automaticStateChange = false; + + this.updateUserGesture(1); + this.updateUserPosture('std'); + } + + this.updatePreviewRoomView(); + + return RoomPreviewer.PREVIEW_OBJECT_ID; + } + + return -1; + } + + public updateUserPosture(type: string, parameter: string = ''): void + { + if(this.isRoomEngineReady) this._roomEngine.updateRoomObjectUserPosture(this._previewRoomId, RoomPreviewer.PREVIEW_OBJECT_ID, type, parameter); + } + + public updateUserGesture(gestureId: number): void + { + if(this.isRoomEngineReady) this._roomEngine.updateRoomObjectUserGesture(this._previewRoomId, RoomPreviewer.PREVIEW_OBJECT_ID, gestureId); + } + + public updateUserEffect(effectId: number): void + { + if(this.isRoomEngineReady) this._roomEngine.updateRoomObjectUserEffect(this._previewRoomId, RoomPreviewer.PREVIEW_OBJECT_ID, effectId); + } + + public updateObjectUserFigure(figure: string, gender: string = null, subType: string = null, isRiding: boolean = false): boolean + { + if(this.isRoomEngineReady) return this._roomEngine.updateRoomObjectUserFigure(this._previewRoomId, RoomPreviewer.PREVIEW_OBJECT_ID, figure, gender, subType, isRiding); + + return false; + } + + public updateObjectUserAction(action: string, value: number, parameter: string = null): void + { + if(this.isRoomEngineReady) this._roomEngine.updateRoomObjectUserAction(this._previewRoomId, RoomPreviewer.PREVIEW_OBJECT_ID, action, value, parameter); + } + + public changeRoomObjectState(): void + { + if(this.isRoomEngineReady) + { + this._automaticStateChange = false; + + if(this._currentPreviewObjectCategory !== RoomObjectCategory.UNIT) this._roomEngine.changeObjectState(this._previewRoomId, RoomPreviewer.PREVIEW_OBJECT_ID, this._currentPreviewObjectCategory); + } + } + + public changeRoomObjectDirection(): void + { + if(this.isRoomEngineReady) + { + const roomObject = this._roomEngine.getRoomObject(this._previewRoomId, RoomPreviewer.PREVIEW_OBJECT_ID, this._currentPreviewObjectCategory); + + if(!roomObject) return; + + const direction = this._roomEngine.objectEventHandler._Str_17555(roomObject, true); + + switch(this._currentPreviewObjectCategory) + { + case RoomObjectCategory.FLOOR: { + const floorLocation = new Vector3d(RoomPreviewer.PREVIEW_OBJECT_LOCATION_X, RoomPreviewer.PREVIEW_OBJECT_LOCATION_Y); + const floorDirection = new Vector3d(direction, direction, direction); + + this._roomEngine.updateRoomObjectFloor(this._previewRoomId, RoomPreviewer.PREVIEW_OBJECT_ID, floorLocation, floorDirection, null, null); + return; + } + case RoomObjectCategory.WALL: + //this._roomEngine.updateRoomObjectWall(this._previewRoomId, RoomPreviewer.PREVIEW_OBJECT_ID, null, direction, null, null); + return; + } + } + } + + private checkAutomaticRoomObjectStateChange(): void + { + if(this._automaticStateChange) + { + const time = Nitro.instance.time; + + if(time > (this._previousAutomaticStateChangeTime + RoomPreviewer.AUTOMATIC_STATE_CHANGE_INTERVAL)) + { + this._previousAutomaticStateChangeTime = time; + + if(this.isRoomEngineReady) this._roomEngine.changeObjectState(this._previewRoomId, RoomPreviewer.PREVIEW_OBJECT_ID, this._currentPreviewObjectCategory); + } + } + } + + public getRoomCanvas(width: number, height: number): DisplayObject + { + if(this.isRoomEngineReady) + { + const displayObject = (this._roomEngine.getRoomInstanceDisplay(this._previewRoomId, RoomPreviewer.PREVIEW_CANVAS_ID, width, height, this._currentPreviewScale) as Container); + + if(displayObject && (this._backgroundColor !== null)) + { + const background = new Sprite(Texture.WHITE); + + background.width = width; + background.height = height; + background.tint = this._backgroundColor; + + displayObject.addChildAt(background, 0); + } + + this._roomEngine.setRoomInstanceRenderingCanvasMask(this._previewRoomId, RoomPreviewer.PREVIEW_CANVAS_ID, true); + + const geometry = this._roomEngine.getRoomInstanceGeometry(this._previewRoomId, RoomPreviewer.PREVIEW_CANVAS_ID); + + if(geometry) geometry.adjustLocation(new Vector3d(RoomPreviewer.PREVIEW_OBJECT_LOCATION_X, RoomPreviewer.PREVIEW_OBJECT_LOCATION_Y, 0), 30); + + this._currentPreviewCanvasWidth = width; + this._currentPreviewCanvasHeight = height; + + return displayObject; + } + + return null; + } + + public modifyRoomCanvas(width: number, height: number): void + { + if(this.isRoomEngineReady) + { + this._currentPreviewCanvasWidth = width; + this._currentPreviewCanvasHeight = height; + + this._roomEngine.initializeRoomInstanceRenderingCanvas(this._previewRoomId, RoomPreviewer.PREVIEW_CANVAS_ID, width, height); + } + } + + public set addViewOffset(point: Point) + { + this._addViewOffset = point; + } + + public get addViewOffset(): Point + { + return this._addViewOffset; + } + + private updatePreviewObjectBoundingRectangle(point: Point): void + { + const objectBounds = this._roomEngine.getRoomObjectBoundingRectangle(this._previewRoomId, RoomPreviewer.PREVIEW_OBJECT_ID, this._currentPreviewObjectCategory, RoomPreviewer.PREVIEW_CANVAS_ID); + + if(objectBounds && point) + { + objectBounds.x += -(this._currentPreviewCanvasWidth >> 1); + objectBounds.y += -(this._currentPreviewCanvasHeight >> 1); + + objectBounds.x += -(point.x); + objectBounds.y += -(point.y); + + if(!this._currentPreviewRectangle) + { + this._currentPreviewRectangle = objectBounds; + } + else + { + const bounds = this._currentPreviewRectangle.clone().enlarge(objectBounds); + + if(((((bounds.width - this._currentPreviewRectangle.width) > ((this._currentPreviewCanvasWidth - this._currentPreviewRectangle.width) >> 1)) || ((bounds.height - this._currentPreviewRectangle.height) > ((this._currentPreviewCanvasHeight - this._currentPreviewRectangle.height) >> 1))) || (this._currentPreviewRectangle.width < 1)) || (this._currentPreviewRectangle.height < 1)) this._currentPreviewRectangle = bounds; + } + } + } + + private validatePreviewSize(point: Point): Point + { + if(((this._currentPreviewRectangle.width < 1) || (this._currentPreviewRectangle.height < 1))) + { + return point; + } + + if(this.isRoomEngineReady) + { + const geometry = this._roomEngine.getRoomInstanceGeometry(this._previewRoomId, RoomPreviewer.PREVIEW_CANVAS_ID); + + if((this._currentPreviewRectangle.width > (this._currentPreviewCanvasWidth * (1 + RoomPreviewer.ALLOWED_IMAGE_CUT))) || (this._currentPreviewRectangle.height > (this._currentPreviewCanvasHeight * (1 + RoomPreviewer.ALLOWED_IMAGE_CUT)))) + { + if(RoomPreviewer.ZOOM_ENABLED) + { + if(this._roomEngine.getRoomInstanceRenderingCanvasScale(this._previewRoomId, RoomPreviewer.PREVIEW_CANVAS_ID) !== 0.5) + { + this._roomEngine.setRoomInstanceRenderingCanvasScale(this._previewRoomId, RoomPreviewer.PREVIEW_CANVAS_ID, 0.5, null, null); + + this._currentPreviewScale = RoomPreviewer.SCALE_SMALL; + this._currentPreviewNeedsZoomOut = true; + + point.x = (point.x >> 1); + point.y = (point.y >> 1); + + this._currentPreviewRectangle.x = (this._currentPreviewRectangle.x >> 2); + this._currentPreviewRectangle.y = (this._currentPreviewRectangle.y >> 2); + this._currentPreviewRectangle.width = (this._currentPreviewRectangle.width >> 2); + this._currentPreviewRectangle.height = (this._currentPreviewRectangle.height >> 2); + } + } + else + { + if(geometry.isZoomedIn()) + { + geometry.performZoomOut(); + + this._currentPreviewScale = RoomPreviewer.SCALE_SMALL; + this._currentPreviewNeedsZoomOut = true; + } + } + } + + else if(!this._currentPreviewNeedsZoomOut) + { + if(RoomPreviewer.ZOOM_ENABLED) + { + if(this._roomEngine.getRoomInstanceRenderingCanvasScale(this._previewRoomId, RoomPreviewer.PREVIEW_CANVAS_ID) !== 1) + { + this._roomEngine.setRoomInstanceRenderingCanvasScale(this._previewRoomId, RoomPreviewer.PREVIEW_CANVAS_ID, 1, null, null); + + this._currentPreviewScale = RoomPreviewer.SCALE_NORMAL; + } + } + else + { + if(!geometry.isZoomedIn()) + { + geometry.performZoomIn(); + + this._currentPreviewScale = RoomPreviewer.SCALE_NORMAL; + } + } + } + } + + return point; + } + + public zoomIn(): void + { + if(this.isRoomEngineReady) + { + if(RoomPreviewer.ZOOM_ENABLED) + { + this._roomEngine.setRoomInstanceRenderingCanvasScale(this._previewRoomId, RoomPreviewer.PREVIEW_CANVAS_ID, 1); + } + else + { + const geometry = this._roomEngine.getRoomInstanceGeometry(this._previewRoomId, RoomPreviewer.PREVIEW_CANVAS_ID); + + geometry.performZoomIn(); + } + } + + this._currentPreviewScale = RoomPreviewer.SCALE_NORMAL; + } + + public zoomOut(): void + { + if(this.isRoomEngineReady) + { + if(RoomPreviewer.ZOOM_ENABLED) + { + this._roomEngine.setRoomInstanceRenderingCanvasScale(this._previewRoomId, RoomPreviewer.PREVIEW_CANVAS_ID, 0.5); + } + else + { + const geometry = this._roomEngine.getRoomInstanceGeometry(this._previewRoomId, RoomPreviewer.PREVIEW_CANVAS_ID); + + geometry.performZoomOut(); + } + } + + this._currentPreviewScale = RoomPreviewer.SCALE_SMALL; + } + + public updateAvatarDirection(direction: number, headDirection: number): void + { + if(this.isRoomEngineReady) + { + this._roomEngine.updateRoomObjectUserLocation(this._previewRoomId, RoomPreviewer.PREVIEW_OBJECT_ID, new Vector3d(RoomPreviewer.PREVIEW_OBJECT_LOCATION_X, RoomPreviewer.PREVIEW_OBJECT_LOCATION_Y, 0), new Vector3d(RoomPreviewer.PREVIEW_OBJECT_LOCATION_X, RoomPreviewer.PREVIEW_OBJECT_LOCATION_Y, 0), false, 0, new Vector3d((direction * 45), 0, 0), (headDirection * 45)); + } + } + + public updateObjectRoom(floorType: string = null, wallType: string = null, landscapeType: string = null, _arg_4: boolean = false): boolean + { + if(this.isRoomEngineReady) return this._roomEngine.updateRoomInstancePlaneType(this._previewRoomId, floorType, wallType, landscapeType, _arg_4); + + return false; + } + + public updateRoomWallsAndFloorVisibility(wallsVisible: boolean, floorsVisible: boolean = true): void + { + if(this.isRoomEngineReady) this._roomEngine.updateRoomInstancePlaneVisibility(this._previewRoomId, wallsVisible, floorsVisible); + } + + private getCanvasOffset(point: Point): Point + { + if(((this._currentPreviewRectangle.width < 1) || (this._currentPreviewRectangle.height < 1))) return point; + + let x = (-(this._currentPreviewRectangle.left + this._currentPreviewRectangle.right) >> 1); + let y = (-(this._currentPreviewRectangle.top + this._currentPreviewRectangle.bottom) >> 1); + const height = ((this._currentPreviewCanvasHeight - this._currentPreviewRectangle.height) >> 1); + + if(height > 10) + { + y = (y + Math.min(15, (height - 10))); + } + else + { + if(this._currentPreviewObjectCategory !== RoomObjectCategory.UNIT) + { + y = (y + (5 - Math.max(0, (height / 2)))); + } + else + { + y = (y - (5 - Math.min(0, (height / 2)))); + } + } + + y = (y + this._addViewOffset.y); + x = (x + this._addViewOffset.x); + + const offsetX = (x - point.x); + const offsetY = (y - point.y); + + if((offsetX !== 0) || (offsetY !== 0)) + { + const _local_7 = Math.sqrt(((offsetX * offsetX) + (offsetY * offsetY))); + + if(_local_7 > 10) + { + x = (point.x + ((offsetX * 10) / _local_7)); + y = (point.y + ((offsetY * 10) / _local_7)); + } + + return new Point(x, y); + } + + return null; + } + + public updatePreviewRoomView(k: boolean = false): void + { + if(this._disableUpdate && !k) return; + + this.checkAutomaticRoomObjectStateChange(); + + if(this.isRoomEngineReady) + { + let offset = this._roomEngine.getRoomInstanceRenderingCanvasOffset(this._previewRoomId, RoomPreviewer.PREVIEW_CANVAS_ID); + + if(offset) + { + this.updatePreviewObjectBoundingRectangle(offset); + + if(this._currentPreviewRectangle) + { + const scale = this._currentPreviewScale; + + offset = this.validatePreviewSize(offset); + + const canvasOffset = this.getCanvasOffset(offset); + + if(canvasOffset) + { + this._roomEngine.setRoomInstanceRenderingCanvasOffset(this._previewRoomId, RoomPreviewer.PREVIEW_CANVAS_ID, canvasOffset); + } + + if(this._currentPreviewScale !== scale) this._currentPreviewRectangle = null; + } + } + } + } + + public set disableUpdate(flag: boolean) + { + this._disableUpdate = flag; + } + + public set disableRoomEngineUpdate(flag: boolean) + { + if(this.isRoomEngineReady) this._roomEngine.disableUpdate(flag); + } + + private onRoomInitializedonRoomInitialized(event: RoomEngineEvent): void + { + if(!event) return; + + switch(event.type) + { + case RoomEngineEvent.INITIALIZED: + if((event.roomId === this._previewRoomId) && this.isRoomEngineReady) + { + this._roomEngine.updateRoomInstancePlaneType(this._previewRoomId, '110', '99999'); + } + return; + } + } + + private onRoomObjectAdded(event: RoomEngineObjectEvent): void + { + if((event.roomId === this._previewRoomId) && (event.objectId === RoomPreviewer.PREVIEW_OBJECT_ID) && (event.category === this._currentPreviewObjectCategory)) + { + this._currentPreviewRectangle = null; + this._currentPreviewNeedsZoomOut = false; + + const roomObject = this._roomEngine.getRoomObject(event.roomId, event.objectId, event.category); + + if(roomObject && roomObject.model && (event.category === RoomObjectCategory.WALL)) + { + const sizeZ = roomObject.model.getValue(RoomObjectVariable.FURNITURE_SIZE_Z); + const centerZ = roomObject.model.getValue(RoomObjectVariable.FURNITURE_CENTER_Z); + + if((sizeZ !== null) || (centerZ !== null)) + { + this._roomEngine.updateRoomObjectWallLocation(event.roomId, event.objectId, new Vector3d(0.5, 2.3, (((3.6 - sizeZ) / 2) + centerZ))); + } + } + } + } + + public updateRoomEngine(): void + { + if(this.isRoomEngineReady) this._roomEngine.runUpdate(); + } + + public getRenderingCanvas(): IRoomRenderingCanvas + { + const renderingCanvas = this._roomEngine.getRoomInstanceRenderingCanvas(this._previewRoomId, RoomPreviewer.PREVIEW_CANVAS_ID); + + if(!renderingCanvas) return null; + + return renderingCanvas; + } + + public getGenericRoomObjectImage(type: string, value: string, direction: IVector3D, scale: number, listener:IGetImageListener, bgColor: number = 0, extras: string = null, objectData: IObjectData = null, state: number = -1, frame: number = -1, posture: string = null): ImageResult + { + if(this.isRoomEngineReady) + { + return this._roomEngine.getGenericRoomObjectImage(type, value, direction, scale, listener, bgColor, extras, objectData, state, frame, posture); + } + + return null; + } + + public getRoomObjectImage(direction: IVector3D, scale: number, listener: IGetImageListener, bgColor: number = 0): ImageResult + { + if(this.isRoomEngineReady) + { + return this._roomEngine.getRoomObjectImage(this._previewRoomId, RoomPreviewer.PREVIEW_OBJECT_ID, this._currentPreviewObjectCategory, direction, scale, listener, bgColor); + } + + return null; + } + + public getRoomObjectCurrentImage(): RenderTexture + { + if(this.isRoomEngineReady) + { + const roomObject = this._roomEngine.getRoomObject(this._previewRoomId, RoomPreviewer.PREVIEW_OBJECT_ID, RoomObjectCategory.UNIT); + + if(roomObject && roomObject.visualization) return roomObject.visualization.getImage(0xFFFFFF, -1); + } + + return null; + } + + public getRoomPreviewObject(): IRoomObjectController + { + if(this.isRoomEngineReady) + { + const roomObject = this._roomEngine.getRoomObject(this._previewRoomId, RoomPreviewer.PREVIEW_OBJECT_ID, this._currentPreviewObjectCategory); + + if(roomObject) return roomObject; + } + + return null; + } + + public getRoomPreviewOwnRoomObject(): IRoomObjectController + { + if(this.isRoomEngineReady) + { + const roomObject = this._roomEngine.getRoomObject(this._previewRoomId, RoomEngine.ROOM_OBJECT_ID, RoomObjectCategory.ROOM); + + if(roomObject) return roomObject; + } + + return null; + } + + public get isRoomEngineReady(): boolean + { + return (this._roomEngine && this._roomEngine.ready); + } + + public get roomId(): number + { + return this._previewRoomId; + } + + public get backgroundColor(): number + { + return this._backgroundColor; + } + + public set backgroundColor(color: number) + { + this._backgroundColor = color; + } +} diff --git a/src/nitro/room/utils/FurnitureData.ts b/src/nitro/room/utils/FurnitureData.ts new file mode 100644 index 00000000..e7e9d121 --- /dev/null +++ b/src/nitro/room/utils/FurnitureData.ts @@ -0,0 +1,120 @@ +import { IVector3D } from '../../../room/utils/IVector3D'; +import { Vector3d } from '../../../room/utils/Vector3d'; +import { IObjectData } from '../object/data/IObjectData'; + +export class FurnitureData +{ + private _id: number; + private _typeId: number; + private _type: string; + private _location: Vector3d; + private _direction: Vector3d; + private _state: number; + private _data: IObjectData; + private _extra: number; + private _expiryTime: number; + private _usagePolicy: number; + private _ownerId: number; + private _ownerName: string; + private _synchronized: boolean; + private _realRoomObject: boolean; + private _sizeZ: number; + + constructor(id: number, typeId: number, type: string, location: IVector3D, direction: IVector3D, state: number, objectData: IObjectData, extra: number = NaN, expires: number = -1, usagePolicy: number = 0, ownerId: number = 0, ownerName: string = '', synchronized: boolean = true, realRoomObject: boolean = true, sizeZ: number = -1) + { + this._id = id; + this._typeId = typeId; + this._type = type; + this._state = state; + this._data = objectData; + this._extra = extra; + this._expiryTime = expires; + this._usagePolicy = usagePolicy; + this._ownerId = ownerId; + this._ownerName = ownerName; + this._synchronized = synchronized; + this._realRoomObject = realRoomObject; + this._sizeZ = sizeZ; + + this._location = new Vector3d(); + this._direction = new Vector3d(); + + this._location.assign(location); + this._direction.assign(direction); + } + + public get id(): number + { + return this._id; + } + + public get typeId(): number + { + return this._typeId; + } + + public get type(): string + { + return this._type; + } + + public get location(): IVector3D + { + return this._location; + } + + public get direction(): IVector3D + { + return this._direction; + } + + public get state(): number + { + return this._state; + } + + public get data(): IObjectData + { + return this._data; + } + + public get extra(): number + { + return this._extra; + } + + public get expiryTime(): number + { + return this._expiryTime; + } + + public get usagePolicy(): number + { + return this._usagePolicy; + } + + public get ownerId(): number + { + return this._ownerId; + } + + public get ownerName(): string + { + return this._ownerName; + } + + public get synchronized(): boolean + { + return this._synchronized; + } + + public get realRoomObject(): boolean + { + return this._realRoomObject; + } + + public get sizeZ(): number + { + return this._sizeZ; + } +} \ No newline at end of file diff --git a/src/nitro/room/utils/FurnitureStackingHeightMap.ts b/src/nitro/room/utils/FurnitureStackingHeightMap.ts new file mode 100644 index 00000000..3dca78a4 --- /dev/null +++ b/src/nitro/room/utils/FurnitureStackingHeightMap.ts @@ -0,0 +1,119 @@ +export class FurnitureStackingHeightMap +{ + private _width: number; + private _height: number; + private _heights: number[] + private _isNotStackable: boolean[]; + private _isRoomTile: boolean[]; + + constructor(width: number, height: number) + { + this._width = width; + this._height = height; + this._heights = []; + this._isNotStackable = []; + this._isRoomTile = []; + + let total = (width * height); + + while(total > 0) + { + this._heights.push(0); + this._isNotStackable.push(false); + this._isRoomTile.push(false); + + total--; + } + } + + public dispose(): void + { + this._width = 0; + this._height =0; + this._height = null; + this._isNotStackable = null; + this._isRoomTile = null; + } + + private validPosition(x: number, y: number): boolean + { + return (((x >= 0) && (x < this._width)) && (y >= 0)) && (y < this._height); + } + + public getTileHeight(x: number, y: number): number + { + return ((this.validPosition(x, y)) ? this._heights[((y * this._width) + x)] : 0); + } + + public setTileHeight(x: number, y: number, height: number): void + { + if(this.validPosition(x, y)) this._heights[((y * this._width) + x)] = height; + } + + public setStackingBlocked(x: number, y: number, isNotStackable: boolean): void + { + if(this.validPosition(x, y)) this._isNotStackable[((y * this._width) + x)] = isNotStackable; + } + + public setIsRoomTile(x: number, y: number, isRoomTile: boolean): void + { + if(this.validPosition(x, y)) this._isRoomTile[((y * this._width) + x)] = isRoomTile; + } + + public validateLocation(k: number, _arg_2: number, _arg_3: number, _arg_4: number, _arg_5: number, _arg_6: number, _arg_7: number, _arg_8: number, _arg_9: boolean, _arg_10: number = -1): boolean + { + let _local_12 = 0; + let _local_13 = 0; + + if(!this.validPosition(k, _arg_2) || !this.validPosition(((k + _arg_3) - 1), ((_arg_2 + _arg_4) - 1))) return false; + + if(((_arg_5 < 0) || (_arg_5 >= this._width))) _arg_5 = 0; + + if(((_arg_6 < 0) || (_arg_6 >= this._height))) _arg_6 = 0; + + _arg_7 = Math.min(_arg_7, (this._width - _arg_5)); + _arg_8 = Math.min(_arg_8, (this._height - _arg_6)); + + if(_arg_10 === -1) _arg_10 = this.getTileHeight(k, _arg_2); + + let _local_11 = _arg_2; + + while(_local_11 < (_arg_2 + _arg_4)) + { + _local_12 = k; + + while(_local_12 < (k + _arg_3)) + { + if(((((_local_12 < _arg_5) || (_local_12 >= (_arg_5 + _arg_7))) || (_local_11 < _arg_6)) || (_local_11 >= (_arg_6 + _arg_8)))) + { + _local_13 = ((_local_11 * this._width) + _local_12); + + if(_arg_9) + { + if(!this._isRoomTile[_local_13]) return false; + } + else + { + if(((this._isNotStackable[_local_13]) || (!(this._isRoomTile[_local_13]))) || (Math.abs((this._heights[_local_13] - _arg_10)) > 0.01)) return false; + } + } + + _local_12++; + } + + _local_11++; + } + + return true; + } + + public get width(): number + { + return this._width; + } + + public get height(): number + { + return this._height; + } +} \ No newline at end of file diff --git a/src/nitro/room/utils/LegacyWallGeometry.ts b/src/nitro/room/utils/LegacyWallGeometry.ts new file mode 100644 index 00000000..cf0d9b19 --- /dev/null +++ b/src/nitro/room/utils/LegacyWallGeometry.ts @@ -0,0 +1,324 @@ +import { IVector3D } from '../../../room/utils/IVector3D'; +import { Vector3d } from '../../../room/utils/Vector3d'; + +export class LegacyWallGeometry +{ + public static DEFAULT_SCALE: number = 32; + + private static L: string = 'l'; + private static R: string = 'r'; + + private _isDisposed: boolean; + private _scale: number; + private _heightMap: number[][]; + private _width: number; + private _height: number; + private _floorHeight: number; + + constructor() + { + this._isDisposed = false; + this._scale = 64; + this._heightMap = []; + this._width = 0; + this._height = 0; + this._floorHeight = 0; + } + + public get disposed(): boolean + { + return this._isDisposed; + } + + public get scale(): number + { + return this._scale; + } + + public set scale(k: number) + { + this._scale = k; + } + + public dispose(): void + { + this.reset(); + this._isDisposed = true; + } + + public initialize(width: number, height: number, floorHeight: number): void + { + if((width <= this._width) && (height <= this._height)) + { + this._width = width; + this._height = height; + this._floorHeight = floorHeight; + + return; + } + + this.reset(); + + let y = 0; + + while(y < height) + { + const heights: number[] = []; + + this._heightMap.push(heights); + + let x = 0; + + while(x < width) + { + heights.push(0); + + x++; + } + + y++; + } + + this._width = width; + this._height = height; + this._floorHeight = floorHeight; + } + + private reset(): void + { + this._heightMap = []; + } + + public setHeight(x: number, y: number, height: number): boolean + { + if((((x < 0) || (x >= this._width)) || (y < 0)) || (y >= this._height)) return false; + + const heightMap = this._heightMap[y]; + + if(!heightMap) return false; + + heightMap[x] = height; + + return true; + } + + public getHeight(x: number, y: number): number + { + if((((x < 0) || (x >= this._width)) || (y < 0)) || (y >= this._height)) return 0; + + const heightMap = this._heightMap[y]; + + if(!heightMap) return 0; + + return heightMap[x]; + } + + public getLocation(k: number, _arg_2: number, _arg_3: number, _arg_4: number, _arg_5: string): IVector3D + { + let _local_12: number; + let _local_6: number; + let _local_7: number; + if(((k == 0) && (_arg_2 == 0))) + { + k = this._width; + _arg_2 = this._height; + _local_12 = Math.round((this.scale / 10)); + if(_arg_5 == LegacyWallGeometry.R) + { + _local_7 = (this._width - 1); + while(_local_7 >= 0) + { + _local_6 = 1; + while(_local_6 < this._height) + { + if(this.getHeight(_local_7, _local_6) <= this._floorHeight) + { + if((_local_6 - 1) < _arg_2) + { + k = _local_7; + _arg_2 = (_local_6 - 1); + } + break; + } + _local_6++; + } + _local_7--; + } + _arg_4 = (_arg_4 + ((this.scale / 4) - (_local_12 / 2))); + _arg_3 = (_arg_3 + (this.scale / 2)); + } + else + { + _local_6 = (this._height - 1); + while(_local_6 >= 0) + { + _local_7 = 1; + while(_local_7 < this._width) + { + if(this.getHeight(_local_7, _local_6) <= this._floorHeight) + { + if((_local_7 - 1) < k) + { + k = (_local_7 - 1); + _arg_2 = _local_6; + } + break; + } + _local_7++; + } + _local_6--; + } + _arg_4 = (_arg_4 + ((this.scale / 4) - (_local_12 / 2))); + _arg_3 = (_arg_3 - _local_12); + } + } + let _local_8: number = k; + let _local_9: number = _arg_2; + let _local_10: number = this.getHeight(k, _arg_2); + if(_arg_5 == LegacyWallGeometry.R) + { + _local_8 = (_local_8 + ((_arg_3 / (this._scale / 2)) - 0.5)); + _local_9 = (_local_9 + 0.5); + _local_10 = (_local_10 - ((_arg_4 - (_arg_3 / 2)) / (this._scale / 2))); + } + else + { + _local_9 = (_local_9 + ((((this._scale / 2) - _arg_3) / (this._scale / 2)) - 0.5)); + _local_8 = (_local_8 + 0.5); + _local_10 = (_local_10 - ((_arg_4 - (((this._scale / 2) - _arg_3) / 2)) / (this._scale / 2))); + } + const _local_11:Vector3d = new Vector3d(_local_8, _local_9, _local_10); + return _local_11; + } + + public _Str_24084(k: number, _arg_2: number, _arg_3: string):IVector3D + { + let _local_4: number; + let _local_5: number; + let _local_6 = 0; + let _local_7 = 0; + _local_5 = Math.ceil(k); + _local_6 = (_local_5 - k); + let _local_8: number; + let _local_9: number; + let _local_11: number; + let _local_12 = 0; + _local_4 = 0; + while(_local_4 < this._width) + { + if(((_local_5 >= 0) && (_local_5 < this._height))) + { + if(this.getHeight(_local_4, _local_5) <= this._floorHeight) + { + _local_8 = (_local_4 - 1); + _local_9 = _local_5; + _local_7 = _local_4; + _arg_3 = LegacyWallGeometry.L; + break; + } + if(this.getHeight(_local_4, (_local_5 + 1)) <= this._floorHeight) + { + _local_8 = _local_4; + _local_9 = _local_5; + _local_7 = (_local_9 - k); + _arg_3 = LegacyWallGeometry.R; + break; + } + } + _local_5++; + _local_4++; + } + const _local_10 = ((this.scale / 2) * _local_6); + let _local_13: number = ((-(_local_7) * this.scale) / 2); + _local_13 = (_local_13 + ((((-(_arg_2) * 18) / 32) * this.scale) / 2)); + _local_12 = this.getHeight(_local_8, _local_9); + _local_11 = (((_local_12 * this.scale) / 2) + _local_13); + if(_arg_3 == LegacyWallGeometry.R) + { + _local_11 = (_local_11 + ((_local_6 * this.scale) / 4)); + } + else + { + _local_11 = (_local_11 + (((1 - _local_6) * this.scale) / 4)); + } + return this.getLocation(_local_8, _local_9, _local_10, _local_11, _arg_3); + } + + public _Str_22875(k:IVector3D, _arg_2: number): [ number, number, number, number, string ] + { + if(k == null) + { + return null; + } + let _local_3 = 0; + let _local_4 = 0; + let _local_5 = 0; + let _local_6 = 0; + let _local_7 = ''; + let _local_8 = 0; + if(_arg_2 == 90) + { + _local_3 = Math.floor((k.x - 0.5)); + _local_4 = Math.floor((k.y + 0.5)); + _local_8 = this.getHeight(_local_3, _local_4); + _local_5 = ((this._scale / 2) - (((k.y - _local_4) + 0.5) * (this._scale / 2))); + _local_6 = (((_local_8 - k.z) * (this._scale / 2)) + (((this._scale / 2) - _local_5) / 2)); + _local_7 = LegacyWallGeometry.L; + } + else + { + if(_arg_2 == 180) + { + _local_3 = Math.floor((k.x + 0.5)); + _local_4 = Math.floor((k.y - 0.5)); + _local_8 = this.getHeight(_local_3, _local_4); + _local_5 = (((k.x + 0.5) - _local_3) * (this._scale / 2)); + _local_6 = (((_local_8 - k.z) * (this._scale / 2)) + (_local_5 / 2)); + _local_7 = LegacyWallGeometry.R; + } + else + { + return null; + } + } + return [_local_3, _local_4, _local_5, _local_6, _local_7]; + } + + public _Str_21860(k:IVector3D, _arg_2: number): string + { + const _local_3 = this._Str_22875(k, _arg_2); + if(_local_3 == null) + { + return null; + } + const _local_4: number = Math.trunc(_local_3[0]); + const _local_5: number = Math.trunc(_local_3[1]); + const _local_6: number = Math.trunc(_local_3[2]); + const _local_7: number = Math.trunc(_local_3[3]); + const _local_8: string = _local_3[4]; + const _local_9: string = (((((((((':w=' + _local_4) + ',') + _local_5) + ' l=') + _local_6) + ',') + _local_7) + ' ') + _local_8); + return _local_9; + } + + public getDirection(k: string): number + { + if(k == LegacyWallGeometry.R) + { + return 180; + } + return 90; + } + + public _Str_24141(k: number, _arg_2: number): number + { + const _local_3 = this.getHeight(k, _arg_2); + const _local_4 = (_local_3 + 1); + + return _local_3 + (((((((((Math.trunc(this.getHeight((k - 1), (_arg_2 - 1))) == _local_4) || (Math.trunc(this.getHeight(k, (_arg_2 - 1))) == _local_4)) || (Math.trunc(this.getHeight((k + 1), (_arg_2 - 1))) == _local_4)) || (Math.trunc(this.getHeight((k - 1), _arg_2)) == _local_4)) || (Math.trunc(this.getHeight((k + 1), _arg_2)) == _local_4)) || (Math.trunc(this.getHeight((k - 1), (_arg_2 + 1))) == _local_4)) || (Math.trunc(this.getHeight(k, (_arg_2 + 1))) == _local_4)) || (Math.trunc(this.getHeight((k + 1), (_arg_2 + 1))) == _local_4)) ? 0.5 : 0); + } + + public _Str_10375(k: number, _arg_2: number): boolean + { + return ((((k >= 0) && (k < this._width)) && (_arg_2 >= 0)) && (_arg_2 < this._height)) && (this._heightMap[_arg_2][k] >= 0); + } +} \ No newline at end of file diff --git a/src/nitro/room/utils/ObjectRolling.ts b/src/nitro/room/utils/ObjectRolling.ts new file mode 100644 index 00000000..46512ddb --- /dev/null +++ b/src/nitro/room/utils/ObjectRolling.ts @@ -0,0 +1,40 @@ +import { IVector3D } from '../../../room/utils/IVector3D'; + +export class ObjectRolling +{ + public static MOVE: string = 'mv'; + public static SLIDE: string = 'sld'; + + private _id: number; + private _location: IVector3D; + private _targetLocation: IVector3D; + private _movementType: string; + + constructor(id: number, location: IVector3D, targetLocation: IVector3D, movementType: string = null) + { + this._id = id; + this._location = location; + this._targetLocation = targetLocation; + this._movementType = movementType; + } + + public get id(): number + { + return this._id; + } + + public get location(): IVector3D + { + return this._location; + } + + public get targetLocation(): IVector3D + { + return this._targetLocation; + } + + public get movementType(): string + { + return this._movementType; + } +} \ No newline at end of file diff --git a/src/nitro/room/utils/RoomCamera.ts b/src/nitro/room/utils/RoomCamera.ts new file mode 100644 index 00000000..2d80d065 --- /dev/null +++ b/src/nitro/room/utils/RoomCamera.ts @@ -0,0 +1,288 @@ +import { IVector3D } from '../../../room/utils/IVector3D'; +import { Vector3d } from '../../../room/utils/Vector3d'; + +export class RoomCamera +{ + private static MOVE_SPEED_DENOMINATOR: number = 12; + + private _targetId: number = -1; + private _targetCategory: number = -2; + private _targetLoc:Vector3d = null; + private _moveDistance: number = 0; + private _previousMoveSpeed: number = 0; + private _maintainPreviousMoveSpeed: boolean = false; + private _currentLoc:Vector3d = null; + private _targetObjectLoc:Vector3d; + private _limitedLocX: boolean = false; + private _limitedLocY: boolean = false; + private _centeredLocX: boolean = false; + private _centeredLocY: boolean = false; + private _screenWd: number = 0; + private _screenHt: number = 0; + private _scale: number = 0; + private _roomWd: number = 0; + private _roomHt: number = 0; + private _geometryUpdateId: number = -1; + private _scaleChanged: boolean = false; + private _followDuration: number; + + constructor() + { + this._targetObjectLoc = new Vector3d(); + } + + public get location():IVector3D + { + return this._currentLoc; + } + + public get _Str_10760(): number + { + return this._targetId; + } + + public set _Str_10760(k: number) + { + this._targetId = k; + } + + public get _Str_16562(): number + { + return this._targetCategory; + } + + public set _Str_16562(k: number) + { + this._targetCategory = k; + } + + public get _Str_16185():IVector3D + { + return this._targetObjectLoc; + } + + public set _Str_16185(k:IVector3D) + { + this._targetObjectLoc.assign(k); + } + + public get _Str_10235(): boolean + { + return this._limitedLocX; + } + + public set _Str_10235(k: boolean) + { + this._limitedLocX = k; + } + + public get _Str_10446(): boolean + { + return this._limitedLocY; + } + + public set _Str_10446(k: boolean) + { + this._limitedLocY = k; + } + + public get _Str_8564(): boolean + { + return this._centeredLocX; + } + + public set _Str_8564(k: boolean) + { + this._centeredLocX = k; + } + + public get _Str_8690(): boolean + { + return this._centeredLocY; + } + + public set _Str_8690(k: boolean) + { + this._centeredLocY = k; + } + + public get _Str_7609(): number + { + return this._screenWd; + } + + public set _Str_7609(k: number) + { + this._screenWd = k; + } + + public get _Str_7902(): number + { + return this._screenHt; + } + + public set _Str_7902(k: number) + { + this._screenHt = k; + } + + public get scale(): number + { + return this._scale; + } + + public set scale(k: number) + { + if(this._scale != k) + { + this._scale = k; + this._scaleChanged = true; + } + } + + public get _Str_18975(): number + { + return this._roomWd; + } + + public set _Str_18975(k: number) + { + this._roomWd = k; + } + + public get _Str_15953(): number + { + return this._roomHt; + } + + public set _Str_15953(k: number) + { + this._roomHt = k; + } + + public get _Str_16377(): number + { + return this._geometryUpdateId; + } + + public set _Str_16377(k: number) + { + this._geometryUpdateId = k; + } + + public get _Str_12536(): boolean + { + if(((!(this._targetLoc == null)) && (!(this._currentLoc == null)))) + { + return true; + } + return false; + } + + public set target(k:IVector3D) + { + let _local_2:Vector3d; + if(this._targetLoc == null) + { + this._targetLoc = new Vector3d(); + } + if((((!(this._targetLoc.x == k.x)) || (!(this._targetLoc.y == k.y))) || (!(this._targetLoc.z == k.z)))) + { + this._targetLoc.assign(k); + _local_2 = Vector3d.dif(this._targetLoc, this._currentLoc); + this._moveDistance = _local_2.length; + this._maintainPreviousMoveSpeed = true; + } + } + + public dispose(): void + { + this._targetLoc = null; + this._currentLoc = null; + } + + public _Str_20685(k:IVector3D): void + { + if(this._currentLoc != null) + { + return; + } + this._currentLoc = new Vector3d(); + this._currentLoc.assign(k); + } + + public _Str_25467(k:IVector3D): void + { + if(this._currentLoc == null) + { + this._currentLoc = new Vector3d(); + } + this._currentLoc.assign(k); + } + + public update(k: number, _arg_2: number): void + { + let _local_3:Vector3d; + let _local_4: number; + let _local_5: number; + let _local_6: number; + let _local_7: number; + if((((this._followDuration > 0) && (!(this._targetLoc == null))) && (!(this._currentLoc == null)))) + { + if(this._scaleChanged) + { + this._scaleChanged = false; + this._currentLoc = this._targetLoc; + this._targetLoc = null; + return; + } + _local_3 = Vector3d.dif(this._targetLoc, this._currentLoc); + if(_local_3.length > this._moveDistance) + { + this._moveDistance = _local_3.length; + } + if(_local_3.length <= _arg_2) + { + this._currentLoc = this._targetLoc; + this._targetLoc = null; + this._previousMoveSpeed = 0; + } + else + { + _local_4 = Math.sin(((Math.PI * _local_3.length) / this._moveDistance)); + _local_5 = (_arg_2 * 0.5); + _local_6 = (this._moveDistance / RoomCamera.MOVE_SPEED_DENOMINATOR); + _local_7 = (_local_5 + ((_local_6 - _local_5) * _local_4)); + if(this._maintainPreviousMoveSpeed) + { + if(_local_7 < this._previousMoveSpeed) + { + _local_7 = this._previousMoveSpeed; + if(_local_7 > _local_3.length) + { + _local_7 = _local_3.length; + } + } + else + { + this._maintainPreviousMoveSpeed = false; + } + } + this._previousMoveSpeed = _local_7; + _local_3.divide(_local_3.length); + _local_3.multiply(_local_7); + this._currentLoc = Vector3d.sum(this._currentLoc, _local_3); + } + } + } + + public reset(): void + { + this._geometryUpdateId = -1; + } + + public _Str_19465(k: number): void + { + this._followDuration = k; + } +} diff --git a/src/nitro/room/utils/RoomData.ts b/src/nitro/room/utils/RoomData.ts new file mode 100644 index 00000000..2c7e14cd --- /dev/null +++ b/src/nitro/room/utils/RoomData.ts @@ -0,0 +1,59 @@ +import { RoomMapData } from '../object/RoomMapData'; + +export class RoomData +{ + private _roomId: number; + private _data: RoomMapData; + private _floorType: string; + private _wallType: string; + private _landscapeType: string; + + constructor(roomId: number, data: RoomMapData) + { + this._roomId = roomId; + this._data = data; + this._floorType = null; + this._wallType = null; + this._landscapeType = null; + } + + public get roomId(): number + { + return this._roomId; + } + + public get data(): RoomMapData + { + return this._data; + } + + public get floorType(): string + { + return this._floorType; + } + + public set floorType(k: string) + { + this._floorType = k; + } + + public get wallType(): string + { + return this._wallType; + } + + public set wallType(k: string) + { + this._wallType = k; + } + + public get landscapeType(): string + { + return this._landscapeType; + } + + public set landscapeType(k: string) + { + this._landscapeType = k; + } +} \ No newline at end of file diff --git a/src/nitro/room/utils/RoomInstanceData.ts b/src/nitro/room/utils/RoomInstanceData.ts new file mode 100644 index 00000000..0d5cbb73 --- /dev/null +++ b/src/nitro/room/utils/RoomInstanceData.ts @@ -0,0 +1,235 @@ +import { FurnitureData } from './FurnitureData'; +import { FurnitureStackingHeightMap } from './FurnitureStackingHeightMap'; +import { LegacyWallGeometry } from './LegacyWallGeometry'; +import { RoomCamera } from './RoomCamera'; +import { SelectedRoomObjectData } from './SelectedRoomObjectData'; +import { TileObjectMap } from './TileObjectMap'; + +export class RoomInstanceData +{ + private _roomId: number; + + private _modelName: string; + private _legacyGeometry: LegacyWallGeometry; + private _tileObjectMap: TileObjectMap; + private _roomCamera: RoomCamera; + private _selectedObject: SelectedRoomObjectData; + private _placedObject: SelectedRoomObjectData; + private _furnitureStackingHeightMap: FurnitureStackingHeightMap; + + private _floorStack: Map; + private _wallStack: Map; + private _mouseButtonCursorOwners: string[]; + + constructor(roomId: number) + { + this._roomId = roomId; + + this._modelName = null; + this._legacyGeometry = new LegacyWallGeometry(); + this._tileObjectMap = null; + this._roomCamera = new RoomCamera(); + this._selectedObject = null; + this._placedObject = null; + this._furnitureStackingHeightMap = null; + + this._floorStack = new Map(); + this._wallStack = new Map(); + this._mouseButtonCursorOwners = []; + } + + public dispose(): void + { + return; + } + + public setModelName(name: string): void + { + this._modelName = name; + } + + public setSelectedObject(data: SelectedRoomObjectData): void + { + if(this._selectedObject) + { + this._selectedObject.dispose(); + } + + this._selectedObject = data; + } + + public setPlacedObject(data: SelectedRoomObjectData): void + { + if(this._placedObject) + { + this._placedObject.dispose(); + } + + this._placedObject = data; + } + + public setFurnitureStackingHeightMap(heightMap: FurnitureStackingHeightMap): void + { + if(this._furnitureStackingHeightMap) this._furnitureStackingHeightMap.dispose(); + + this._furnitureStackingHeightMap = heightMap; + + if(this._tileObjectMap) this._tileObjectMap.dispose(); + + if(this._furnitureStackingHeightMap) + { + this._tileObjectMap = new TileObjectMap(this._furnitureStackingHeightMap.width, this._furnitureStackingHeightMap.height); + } + } + + public addPendingFurnitureFloor(data: FurnitureData): void + { + if(!data) return; + + this._floorStack.delete(data.id); + this._floorStack.set(data.id, data); + } + + public removePendingFunitureFloor(id: number): FurnitureData + { + const existing = this._floorStack.get(id); + + if(!existing) return null; + + this._floorStack.delete(id); + + return existing; + } + + public getPendingFurnitureFloor(id: number): FurnitureData + { + const existing = this._floorStack.get(id); + + if(!existing) return null; + + this._floorStack.delete(id); + + return existing; + } + + public getNextPendingFurnitureFloor(): FurnitureData + { + if(!this._floorStack.size) return null; + + const keys = this._floorStack.keys(); + + return this.getPendingFurnitureFloor(keys.next().value as number); + } + + public addPendingFurnitureWall(data: FurnitureData): void + { + if(!data) return; + + this._wallStack.delete(data.id); + this._wallStack.set(data.id, data); + } + + public removePendingFurnitureWall(id: number): FurnitureData + { + const existing = this._wallStack.get(id); + + if(!existing) return null; + + this._wallStack.delete(id); + + return existing; + } + + public getPendingFurnitureWall(id: number): FurnitureData + { + const existing = this._wallStack.get(id); + + if(!existing) return null; + + this._wallStack.delete(id); + + return existing; + } + + public getNextPendingFurnitureWall(): FurnitureData + { + if(!this._wallStack.size) return null; + + const keys = this._wallStack.keys(); + + return this.getPendingFurnitureWall(keys.next().value as number); + } + + public _Str_16810(k: string): boolean + { + const _local_2 = this._mouseButtonCursorOwners.indexOf(k); + + if(_local_2 === -1) + { + this._mouseButtonCursorOwners.push(k); + + return true; + } + + return false; + } + + public _Str_11959(k: string): boolean + { + const _local_2 = this._mouseButtonCursorOwners.indexOf(k); + + if(_local_2 > -1) + { + this._mouseButtonCursorOwners.splice(_local_2, 1); + + return true; + } + + return false; + } + + public _Str_22598(): boolean + { + return this._mouseButtonCursorOwners.length > 0; + } + + public get roomId(): number + { + return this._roomId; + } + + public get modelName(): string + { + return this._modelName; + } + + public get legacyGeometry(): LegacyWallGeometry + { + return this._legacyGeometry; + } + + public get tileObjectMap(): TileObjectMap + { + return this._tileObjectMap; + } + + public get roomCamera(): RoomCamera + { + return this._roomCamera; + } + + public get selectedObject(): SelectedRoomObjectData + { + return this._selectedObject; + } + + public get placedObject(): SelectedRoomObjectData + { + return this._placedObject; + } + + public get furnitureStackingHeightMap(): FurnitureStackingHeightMap + { + return this._furnitureStackingHeightMap; + } +} \ No newline at end of file diff --git a/src/nitro/room/utils/RoomObjectBadgeImageAssetListener.ts b/src/nitro/room/utils/RoomObjectBadgeImageAssetListener.ts new file mode 100644 index 00000000..f8442392 --- /dev/null +++ b/src/nitro/room/utils/RoomObjectBadgeImageAssetListener.ts @@ -0,0 +1,23 @@ +import { IRoomObjectController } from '../../../room/object/IRoomObjectController'; + +export class RoomObjectBadgeImageAssetListener +{ + private _object: IRoomObjectController; + private _groupBadge: boolean; + + constructor(object: IRoomObjectController, groupBadge: boolean) + { + this._object = object; + this._groupBadge = groupBadge; + } + + public get object(): IRoomObjectController + { + return this._object; + } + + public get groupBadge(): boolean + { + return this._groupBadge; + } +} \ No newline at end of file diff --git a/src/nitro/room/utils/SelectedRoomObjectData.ts b/src/nitro/room/utils/SelectedRoomObjectData.ts new file mode 100644 index 00000000..23667e98 --- /dev/null +++ b/src/nitro/room/utils/SelectedRoomObjectData.ts @@ -0,0 +1,97 @@ +import { IVector3D } from '../../../room/utils/IVector3D'; +import { Vector3d } from '../../../room/utils/Vector3d'; +import { ISelectedRoomObjectData } from '../ISelectedRoomObjectData'; +import { IObjectData } from '../object/data/IObjectData'; + +export class SelectedRoomObjectData implements ISelectedRoomObjectData +{ + private _id: number = 0; + private _category: number = 0; + private _operation: string = ''; + private _loc: Vector3d = null; + private _dir: Vector3d = null; + private _typeId: number = 0; + private _instanceData: string = null; + private _stuffData: IObjectData = null; + private _state: number = -1; + private _animFrame: number = -1; + private _posture: string = null; + + constructor(id: number, category: number, operation: string, location: IVector3D, direction: IVector3D, typeId: number = 0, instanceData: string = null, stuffData: IObjectData = null, state: number = -1, frameNumber: number = -1, posture: string = null) + { + this._id = id; + this._category = category; + this._operation = operation; + this._loc = new Vector3d(); + this._loc.assign(location); + this._dir = new Vector3d(); + this._dir.assign(direction); + this._typeId = typeId; + this._instanceData = instanceData; + this._stuffData = stuffData; + this._state = state; + this._animFrame = frameNumber; + this._posture = posture; + } + + public get id(): number + { + return this._id; + } + + public get category(): number + { + return this._category; + } + + public get operation(): string + { + return this._operation; + } + + public get loc():Vector3d + { + return this._loc; + } + + public get dir():Vector3d + { + return this._dir; + } + + public get typeId(): number + { + return this._typeId; + } + + public get _Str_4766(): string + { + return this._instanceData; + } + + public get stuffData(): IObjectData + { + return this._stuffData; + } + + public get state(): number + { + return this._state; + } + + public get _Str_15896(): number + { + return this._animFrame; + } + + public get posture(): string + { + return this._posture; + } + + public dispose(): void + { + this._loc = null; + this._dir = null; + } +} \ No newline at end of file diff --git a/src/nitro/room/utils/SpriteDataCollector.ts b/src/nitro/room/utils/SpriteDataCollector.ts new file mode 100644 index 00000000..07607bb6 --- /dev/null +++ b/src/nitro/room/utils/SpriteDataCollector.ts @@ -0,0 +1,460 @@ +import { Point, Rectangle } from 'pixi.js'; +import { RoomObjectSpriteData } from '../../../room/data/RoomObjectSpriteData'; +import { IPlaneDrawingData } from '../../../room/object/visualization/IPlaneDrawingData'; +import { IPlaneVisualization } from '../../../room/object/visualization/IPlaneVisualization'; +import { IRoomObjectSpriteVisualization } from '../../../room/object/visualization/IRoomObjectSpriteVisualization'; +import { IRoomPlane } from '../../../room/object/visualization/IRoomPlane'; +import { IRoomRenderingCanvas } from '../../../room/renderer/IRoomRenderingCanvas'; +import { Vector3d } from '../../../room/utils/Vector3d'; +import { Nitro } from '../../Nitro'; +import { RoomObjectCategory } from '../object/RoomObjectCategory'; +import { PlaneDrawingData } from '../object/visualization/room/PlaneDrawingData'; +import { RoomEngine } from '../RoomEngine'; + +export class SpriteDataCollector +{ + private static _Str_16967: number = 1; + private static _Str_18197: number = -16; + private static _Str_18565: number = -52; + private static _Str_17558: number = 30; + + private _Str_6409: number; + private _Str_3008: number = 0; + private _Str_18433: number = 0; + + private static _Str_22230(k: RoomObjectSpriteData[], _arg_2: RoomEngine): RoomObjectSpriteData[] + { + const datas: RoomObjectSpriteData[] = []; + + for(const data of k) + { + if(!data) continue; + + if((data.type === 'boutique_mannequin1') && (data.name.indexOf('mannequin_') === 0)) + { + const roomObject = _arg_2.getRoomObject(_arg_2.activeRoomId, data.objectId, RoomObjectCategory.FLOOR); + + if(roomObject) + { + const spriteList = (roomObject.visualization as IRoomObjectSpriteVisualization).getSpriteList(); + + if(spriteList) + { + for(const sprite of spriteList) + { + sprite.x = (sprite.x + ((data.x + (data.width / 2)) + SpriteDataCollector._Str_16967)); + sprite.y = (sprite.y + ((data.y + data.height) + SpriteDataCollector._Str_18197)); + sprite.z = (sprite.z + data.z); + datas.push(sprite); + } + } + } + } + else + { + datas.push(data); + } + } + + return datas; + } + + private static _Str_22564(k: RoomObjectSpriteData, _arg_2: RoomObjectSpriteData): number + { + if(k.z < _arg_2.z) return 1; + + if(k.z > _arg_2.z) return -1; + + return -1; + } + + private static _Str_20789(k:RoomObjectSpriteData, _arg_2: Rectangle, _arg_3: IRoomRenderingCanvas): boolean + { + return true; + // var _local_4 = new Rectangle((k.x + _arg_3.screenOffsetX), (k.y + _arg_3.screenOffsetY), k.width, k.height); + // // intersects + // return _local_4.contains(_arg_2.x, _arg_2.y); + } + + private static _Str_14110(k: Point, _arg_2: Point, _arg_3: Point, _arg_4: Point): Point[] + { + const points: Point[] = []; + + if(k.x == _arg_2.x) + { + points.push(k, _arg_3, _arg_2, _arg_4); + } + else + { + if(k.x == _arg_3.x) + { + points.push(k, _arg_2, _arg_3, _arg_4); + } + else + { + if((((_arg_2.x < k.x) && (_arg_2.y > k.y)) || ((_arg_2.x > k.x) && (_arg_2.y < k.y)))) + { + points.push(k, _arg_3, _arg_2, _arg_4); + } + else + { + points.push(k, _arg_2, _arg_3, _arg_4); + } + } + } + + if(points[0].x < points[1].x) + { + let _local_6 = points[0]; + + points[0] = points[1]; + points[1] = _local_6; + + _local_6 = points[2]; + + points[2] = points[3]; + points[3] = _local_6; + } + + if(points[0].y < points[2].y) + { + let _local_6 = points[0]; + + points[0] = points[2]; + points[2] = _local_6; + + _local_6 = points[1]; + + points[1] = points[3]; + points[3] = _local_6; + } + + return points; + } + + + public _Str_4536(k: Rectangle, _arg_2:IRoomRenderingCanvas, _arg_3:RoomEngine, _arg_4: number): string + { + const _local_5: Object[] = []; + let _local_6 = _arg_2.getSortableSpriteList(); + + const _local_7 = _arg_3._Str_21072(_arg_3.activeRoomId, RoomObjectCategory.UNIT); + + for(const _local_8 of _local_7) + { + if(_local_8.id !== _arg_4) + { + const _local_11 = (_local_8.visualization as IRoomObjectSpriteVisualization).getSpriteList(); + + if(_local_11) + { + let _local_12 = 0; + let _local_13 = 0; + + for(const _local_14 of _local_6) + { + if(_local_14.name === ('avatar_' + _local_8.id)) + { + _local_12 = _local_14.z; + _local_13 = ((_local_14.y + _local_14.height) - (_arg_2.geometry.scale / 4)); + + break; + } + } + + const _local_15 = _arg_3.getRoomObjectScreenLocation(_arg_3.activeRoomId, _local_8.id, RoomObjectCategory.UNIT, _arg_2.id); + + if(_local_15) + { + if(_local_13 === 0) _local_13 = _local_15.y; + + for(const _local_16 of _local_11) + { + _local_16.x = (_local_16.x + (_local_15.x - _arg_2.screenOffsetX)); + _local_16.y = (_local_16.y + _local_13); + _local_16.z = (_local_16.z + _local_12); + + if(((_local_16.name.indexOf('h_std_fx29_') === 0) || (_local_16.name.indexOf('h_std_fx185_') === 0))) + { + _local_16.y = (_local_16.y + SpriteDataCollector._Str_18565); + } + + _local_6.push(_local_16); + } + } + } + } + } + + _local_6 = SpriteDataCollector._Str_22230(_local_6, _arg_3); + _local_6.sort(SpriteDataCollector._Str_22564); + + for(const _local_9 of _local_6) + { + if((((((!(_local_9.name === null)) && (_local_9.name.length > 0)) && (!(_local_9.name.indexOf('tile_cursor_') === 0))) && (SpriteDataCollector._Str_20789(_local_9, k, _arg_2))) && ((_arg_4 < 0) || (!(_local_9.objectId == _arg_4))))) + { + _local_5.push(this._Str_25132(_local_9, k, _arg_2, _arg_3)); + + if(!this._Str_6409) this._Str_6409 = _local_9.z; + + this._Str_3008++; + } + } + + return JSON.stringify(_local_5); + } + + public _Str_24177(k: RoomEngine): string + { + return JSON.stringify(new Object()); + } + + private _Str_25132(k: RoomObjectSpriteData, _arg_2: Rectangle, _arg_3: IRoomRenderingCanvas, _arg_4: RoomEngine): Object + { + let _local_7: string = null; + let _local_9: string[] = []; + + const _local_5: { + name?: string, + x?: number, + y?: number, + z?: number, + alpha?: number, + flipH?: boolean, + skew?: number, + frame?: boolean, + color?: number, + blendMode?: string, + width?: number, + height?: number, + posture?: string + } = {}; + + let _local_6 = k.name; + + if(k.name.indexOf('@') !== -1) + { + _local_9 = k.name.split('@'); + _local_6 = _local_9[0]; + _local_7 = _local_9[1]; + } + + // if(((_local_7) && (k.type))) + // { + // const _local_10 = _arg_4.roomContentLoader.getCollection(k.type); + + // if(_local_10) + // { + // const _local_11 = _local_10.getPalette(_local_7); + + // if (((!(_local_11 == null)) && (!(_local_11.@source == null)))) + // { + // _local_5.paletteSourceName = (_local_11.@source + ''); + // } + // } + // } + + // var _local_8:String = _arg_4.configuration.getProperty('image.library.url'); + // _local_6 = _local_6.replace('%image.library.url%', _local_8); + // if (_local_6.indexOf('%group.badge.url%') != -1) + // { + // _local_12 = _arg_4.configuration.getProperty('group.badge.url'); + // _local_6 = _local_6.replace('%group.badge.url%', ''); + // _local_13 = _local_12.replace('%imagerdata%', _local_6); + // _local_6 = _local_13; + // } + + _local_5.name = _local_6; + _local_5.x = (k.x - _arg_2.x); + _local_5.y = (k.y - _arg_2.y); + _local_5.x = (_local_5.x + _arg_3.screenOffsetX); + _local_5.y = (_local_5.y + _arg_3.screenOffsetY); + _local_5.z = k.z; + + if(k.alpha && (k.alpha.toString() !== '255')) _local_5.alpha = k.alpha; + + if(k.flipH) _local_5.flipH = k.flipH; + + if(k.skew) _local_5.skew = k.skew; + + if(k.frame) _local_5.frame = k.frame; + + if(k.color && (k.color.length > 0)) _local_5.color = parseInt(k.color); + + if(k.blendMode && (k.blendMode !== 'normal')) _local_5.blendMode = k.blendMode; + + if(_local_6.indexOf('http') === 0) + { + _local_5.width = k.width; + _local_5.height = k.height; + + this._Str_18433++; + + if(this._Str_18433 > SpriteDataCollector._Str_17558) _local_5.name = 'box'; + } + + if(k.posture) _local_5.posture = k.posture; + + return _local_5; + } + + private _Str_25196(k: Rectangle, _arg_2: number, _arg_3: IPlaneDrawingData[]): PlaneDrawingData + { + const _local_4 = new Point(0, 0); + const _local_5 = new Point(k.width, 0); + const _local_6 = new Point(0, k.height); + const _local_7 = new Point(k.width, k.height); + const _local_8 = SpriteDataCollector._Str_14110(_local_4, _local_5, _local_6, _local_7); + + let _local_9 = 0; + + if(_arg_3.length > 0) + { + _local_9 = _arg_3[0].z; + + if(this._Str_6409) _local_9 = Math.max(this._Str_6409, _local_9); + } + else + { + _local_9 = ((this._Str_6409) ? this._Str_6409 : 0); + } + + _local_9 = (_local_9 + ((this._Str_3008 * 1.776104) + (_arg_3.length * 2.31743))); + + const _local_10 = new PlaneDrawingData(null, _arg_2); + + _local_10.cornerPoints = _local_8; + _local_10.z = _local_9; + + return _local_10; + } + + private _Str_25623(k: IRoomPlane[], _arg_2: IRoomRenderingCanvas, _arg_3: RoomEngine): { plane: IRoomPlane, z: number }[] + { + const _local_4: Map = new Map(); + + let _local_5 = 1; + + if(this._Str_6409) + { + _local_5 = (_local_5 + this._Str_6409); + } + + for(const _local_6 of k) + { + const _local_10 = { + plane: _local_6, + z: _local_5 + }; + + _local_4.set(_local_6.uniqueId, _local_10); + } + + const sprites = _arg_2._Str_14588(); + + sprites.sort((a, b) => + { + return (b.z - a.z); + }); + + sprites.reverse(); + + let _local_8: { plane: IRoomPlane, z: number }[] = []; + + for(const sprite of sprites) + { + const objectSprite = sprite.sprite; + + if(objectSprite) + { + const _local_10 = _local_4.get(objectSprite.id); + + if(_local_10) + { + _local_4.delete(objectSprite.id); + + _local_10.z = sprite.z; + + _local_8.push(_local_10); + } + } + } + + _local_8 = _local_8.concat(Array.from(_local_4.values())); + + return _local_8; + } + + public _Str_22985(k: Rectangle, _arg_2: IRoomRenderingCanvas, _arg_3: RoomEngine, _arg_4: number): PlaneDrawingData[] + { + const _local_5: PlaneDrawingData[] = []; + + const roomObject = _arg_3.getRoomObject(_arg_3.activeRoomId, RoomEngine.ROOM_OBJECT_ID, RoomObjectCategory.ROOM); + const visualization = (roomObject.visualization as unknown as IPlaneVisualization); + + if(visualization) + { + const _local_8 = _arg_2.geometry; + const _local_9 = this._Str_25623(visualization._Str_19113, _arg_2, _arg_3); + const _local_10 = Nitro.instance.stage; + + for(const _local_11 of _local_9) + { + const _local_12 = _local_11.plane; + const _local_13: Point[] = []; + + const _local_14 = Vector3d.sum(_local_12.location, _local_12._Str_5424); + const _local_15 = _local_8.getScreenPoint(_local_12.location); + const _local_16 = _local_8.getScreenPoint(_local_14); + const _local_17 = _local_8.getScreenPoint(Vector3d.sum(_local_12.location, _local_12._Str_4968)); + const _local_18 = _local_8.getScreenPoint(Vector3d.sum(_local_14, _local_12._Str_4968)); + + _local_13.push(_local_15, _local_16, _local_17, _local_18); + + let _local_19 = 0; + let _local_20 = 0; + + for(const _local_21 of _local_13) + { + _local_21.x += (_local_10.width / 2); + _local_21.y += (_local_10.height / 2); + + _local_21.x += _arg_2.screenOffsetX; + _local_21.y += _arg_2.screenOffsetY; + + _local_21.x += -(k.x); + _local_21.y += -(k.y); + + if(_local_21.x < 0) _local_19--; + + else if(_local_21.x >= k.width) _local_19++; + + if(_local_21.y < 0) _local_20--; + + else if(_local_21.y >= k.height) _local_20++; + } + + if(((Math.abs(_local_19) === 4) || (Math.abs(_local_20) === 4))) + { + // + } + else + { + const _local_22 = SpriteDataCollector._Str_14110(_local_15, _local_16, _local_17, _local_18); + + for(const _local_23 of _local_12._Str_22136(_local_8)) + { + _local_23.cornerPoints = _local_22; + _local_23.z = _local_11.z; + + _local_5.push(_local_23); + } + } + } + + _local_5.unshift(this._Str_25196(k, _arg_4, _local_5)); + } + + return _local_5; + } +} diff --git a/src/nitro/room/utils/TileObjectMap.ts b/src/nitro/room/utils/TileObjectMap.ts new file mode 100644 index 00000000..8acc8df7 --- /dev/null +++ b/src/nitro/room/utils/TileObjectMap.ts @@ -0,0 +1,123 @@ +import { NitroLogger } from '../../../core/common/logger/NitroLogger'; +import { IRoomObject } from '../../../room/object/IRoomObject'; +import { RoomObjectVariable } from '../object/RoomObjectVariable'; + +export class TileObjectMap +{ + private _tileObjectMap: Map>; + private _width: number; + private _height: number; + + constructor(k: number, _arg_2: number) + { + this._tileObjectMap = new Map(); + + let index = 0; + + while(index < _arg_2) + { + this._tileObjectMap.set(index, new Map()); + + index++; + } + + this._width = k; + this._height = _arg_2; + } + + public clear(): void + { + for(const k of this._tileObjectMap.values()) + { + if(!k) continue; + + k.clear(); + } + + this._tileObjectMap.clear(); + } + + public populate(k: IRoomObject[]): void + { + this.clear(); + + for(const _local_2 of k) this._Str_21192(_local_2); + } + + public dispose(): void + { + this._tileObjectMap = null; + this._width = 0; + this._height = 0; + } + + public _Str_19056(k: number, _arg_2: number): IRoomObject + { + if((((k >= 0) && (k < this._width)) && (_arg_2 >= 0)) && (_arg_2 < this._height)) + { + const existing = this._tileObjectMap.get(_arg_2); + + if(existing) return existing.get(k); + } + + return null; + } + + public _Str_23932(k: number, _arg_2: number, _arg_3:IRoomObject): void + { + if(!_arg_3.isReady) + { + NitroLogger.log('Assigning non initialized object to tile object map!'); + + return; + } + + if((((k >= 0) && (k < this._width)) && (_arg_2 >= 0)) && (_arg_2 < this._height)) + { + const existing = this._tileObjectMap.get(_arg_2); + + if(existing) existing.set(k, _arg_3); + } + } + + public _Str_21192(k: IRoomObject): void + { + if(!k || !k.model || !k.isReady) return; + + const location = k.getLocation(); + const direction = k.getDirection(); + + if(!location || !direction) return; + + let sizeX = k.model.getValue(RoomObjectVariable.FURNITURE_SIZE_X); + let sizeY = k.model.getValue(RoomObjectVariable.FURNITURE_SIZE_Y); + + if(sizeX < 1) sizeX = 1; + if(sizeY < 1) sizeY = 1; + + const directionNumber = ((Math.trunc((direction.x + 45)) % 360) / 90); + + if((directionNumber === 1) || (directionNumber === 3)) [ sizeX, sizeY ] = [ sizeY, sizeX ]; + + let y = location.y; + + while(y < (location.y + sizeY)) + { + let x = location.x; + + while(x < (location.x + sizeX)) + { + const roomObject = this._Str_19056(x, y); + + if((!(roomObject)) || ((!(roomObject === k)) && (roomObject.getLocation().z <= location.z))) + { + this._Str_23932(x, y, k); + } + + x++; + } + + y++; + } + } +} \ No newline at end of file diff --git a/src/nitro/session/BadgeImageManager.ts b/src/nitro/session/BadgeImageManager.ts new file mode 100644 index 00000000..6bdf786f --- /dev/null +++ b/src/nitro/session/BadgeImageManager.ts @@ -0,0 +1,107 @@ +import { Texture } from 'pixi.js'; +import { IAssetManager } from '../../core/asset/IAssetManager'; +import { IEventDispatcher } from '../../core/events/IEventDispatcher'; +import { Nitro } from '../Nitro'; +import { BadgeInfo } from './BadgeInfo'; +import { BadgeImageReadyEvent } from './events/BadgeImageReadyEvent'; + +export class BadgeImageManager +{ + public static GROUP_BADGE: string = 'group_badge'; + public static NORMAL_BADGE: string = 'normal_badge'; + + private _assets: IAssetManager; + private _events: IEventDispatcher; + private _requestedBadges: Map; + + constructor(assetManager: IAssetManager, eventDispatcher: IEventDispatcher) + { + this._assets = assetManager; + this._events = eventDispatcher; + this._requestedBadges = new Map(); + } + + public dispose(): void + { + this._assets = null; + } + + public getBadgeImage(badgeName: string, type: string = 'normal_badge', load: boolean = true): Texture + { + let badge = this.getBadgeTexture(badgeName, type); + + if(!badge && load) badge = this.getBadgePlaceholder(); + + return badge; + } + + public getBadgeInfo(k: string): BadgeInfo + { + const badge = this.getBadgeTexture(k); + + return (badge) ? new BadgeInfo(badge, false) : new BadgeInfo(this.getBadgePlaceholder(), true); + } + + public loadBadgeImage(badgeName: string, type: string = 'normal_badge'): string + { + if(this._assets.getTexture(badgeName)) return badgeName; + + this.getBadgeTexture(badgeName, type); + + return null; + } + + private getBadgeTexture(badgeName: string, type: string = 'normal_badge'): Texture + { + const existing = this._assets.getTexture(badgeName); + + if(existing) return existing.clone(); + + if(this._requestedBadges.get(badgeName)) return null; + + const url = this.getBadgeUrl(badgeName, type); + + if(url) + { + this._requestedBadges.set(badgeName, true); + + this._assets.downloadAsset(url, (flag: boolean) => + { + if(flag) + { + const texture = this._assets.getTexture(badgeName); + + if(texture && this._events) this._events.dispatchEvent(new BadgeImageReadyEvent(badgeName, texture.clone())); + } + }); + } + + return null; + } + + private getBadgePlaceholder(): Texture + { + const existing = this._assets.getTexture('loading_icon'); + + if(!existing) return null; + + return existing.clone(); + } + + public getBadgeUrl(badge: string, type: string = 'normal_badge'): string + { + let url = null; + + switch(type) + { + case BadgeImageManager.NORMAL_BADGE: + url = (Nitro.instance.getConfiguration('badge.asset.url')).replace('%badgename%', badge); + break; + case BadgeImageManager.GROUP_BADGE: + url = (Nitro.instance.getConfiguration('badge.asset.group.url')).replace('%badgedata%', badge); + break; + } + + return url; + } +} diff --git a/src/nitro/session/BadgeInfo.ts b/src/nitro/session/BadgeInfo.ts new file mode 100644 index 00000000..53a1484f --- /dev/null +++ b/src/nitro/session/BadgeInfo.ts @@ -0,0 +1,23 @@ +import { Texture } from 'pixi.js'; + +export class BadgeInfo +{ + private _image: Texture; + private _placeHolder: boolean; + + constructor(image: Texture, placeHolder: boolean) + { + this._image = image; + this._placeHolder = placeHolder; + } + + public get image(): Texture + { + return this._image; + } + + public get placeHolder(): boolean + { + return this._placeHolder; + } +} \ No newline at end of file diff --git a/src/nitro/session/HabboClubLevelEnum.ts b/src/nitro/session/HabboClubLevelEnum.ts new file mode 100644 index 00000000..e52a706c --- /dev/null +++ b/src/nitro/session/HabboClubLevelEnum.ts @@ -0,0 +1,6 @@ +export class HabboClubLevelEnum +{ + public static _Str_3159: number = 0; + public static _Str_2964: number = 1; + public static _Str_2575: number = 2; +} \ No newline at end of file diff --git a/src/nitro/session/IRoomHandlerListener.ts b/src/nitro/session/IRoomHandlerListener.ts new file mode 100644 index 00000000..85730476 --- /dev/null +++ b/src/nitro/session/IRoomHandlerListener.ts @@ -0,0 +1,10 @@ +import { IEventDispatcher } from '../../core/events/IEventDispatcher'; +import { IRoomSession } from './IRoomSession'; + +export interface IRoomHandlerListener +{ + getSession(id: number): IRoomSession; + sessionUpdate(id: number, type: string): void; + sessionReinitialize(fromRoomId: number, toRoomId: number): void; + events: IEventDispatcher; +} \ No newline at end of file diff --git a/src/nitro/session/IRoomSession.ts b/src/nitro/session/IRoomSession.ts new file mode 100644 index 00000000..6a8116a6 --- /dev/null +++ b/src/nitro/session/IRoomSession.ts @@ -0,0 +1,51 @@ +import { IDisposable } from '../../core/common/disposable/IDisposable'; +import { IConnection } from '../../core/communication/connections/IConnection'; +import { RoomModerationParser } from '../communication/messages/parser/room/data/RoomModerationParser'; +import { UserDataManager } from './UserDataManager'; + +export interface IRoomSession extends IDisposable +{ + openGift(_Str_1577: number): void; + setConnection(connection: IConnection): void; + setControllerLevel(level: number): void; + setOwnRoomIndex(roomIndex: number): void; + setRoomOwner(): void; + start(): boolean; + reset(roomId: number): void; + sendChatMessage(text: string, styleId: number): void; + sendShoutMessage(text: string, styleId: number): void; + sendWhisperMessage(recipientName: string, text: string, styleId: number): void; + sendChatTypingMessage(isTyping: boolean): void; + sendMottoMessage(motto: string): void; + sendDanceMessage(danceId: number): void; + sendExpressionMessage(expression: number): void; + sendSignMessage(sign: number): void; + sendPostureMessage(posture: number): void; + sendDoorbellApprovalMessage(userName: string, flag: boolean): void; + sendAmbassadorAlertMessage(userId: number): void; + sendKickMessage(userId: number): void; + sendMuteMessage(userId: number, minutes: number): void; + sendBanMessage(userId: number, type: string): void; + sendGiveRightsMessage(userId: number): void; + sendTakeRightsMessage(userId: number): void; + updateMoodlightData(_Str_25037: number, _Str_24446: number, color: number, _Str_5123: number, apply: boolean): void; + toggleMoodlightState(): void; + pickupPet(id: number): void; + pickupBot(id: number): void; + requestMoodlightSettings(): void; + connection: IConnection; + userDataManager: UserDataManager; + roomId: number; + state: string; + tradeMode: number; + _Str_7411: boolean; + doorMode: number; + allowPets: boolean; + controllerLevel: number; + ownRoomIndex: number; + isGuildRoom: boolean; + isRoomOwner: boolean; + isDecorating: boolean; + isSpectator: boolean; + moderationSettings: RoomModerationParser; +} diff --git a/src/nitro/session/IRoomSessionManager.ts b/src/nitro/session/IRoomSessionManager.ts new file mode 100644 index 00000000..cf98881f --- /dev/null +++ b/src/nitro/session/IRoomSessionManager.ts @@ -0,0 +1,13 @@ +import { INitroManager } from '../../core/common/INitroManager'; +import { INitroCommunicationManager } from '../communication/INitroCommunicationManager'; +import { IRoomSession } from './IRoomSession'; + +export interface IRoomSessionManager extends INitroManager +{ + getSession(id: number): IRoomSession; + createSession(roomId: number, password?: string): boolean; + startSession(session: IRoomSession): boolean; + removeSession(id: number, openLandingView?: boolean): void; + communication: INitroCommunicationManager; + viewerSession: IRoomSession; +} \ No newline at end of file diff --git a/src/nitro/session/ISessionDataManager.ts b/src/nitro/session/ISessionDataManager.ts new file mode 100644 index 00000000..88c902c8 --- /dev/null +++ b/src/nitro/session/ISessionDataManager.ts @@ -0,0 +1,54 @@ +import { Texture } from 'pixi.js'; +import { INitroManager } from '../../core/common/INitroManager'; +import { INitroCommunicationManager } from '../communication/INitroCommunicationManager'; +import { IFurnitureData } from './furniture/IFurnitureData'; +import { IFurnitureDataListener } from './furniture/IFurnitureDataListener'; +import { IgnoredUsersManager } from './IgnoredUsersManager'; +import { IProductData } from './product/IProductData'; + +export interface ISessionDataManager extends INitroManager +{ + getAllFurnitureData(listener: IFurnitureDataListener): IFurnitureData[]; + removePendingFurniDataListener(listener: IFurnitureDataListener): void; + getFloorItemData(id: number): IFurnitureData; + getFloorItemDataByName(name: string): IFurnitureData; + getWallItemData(id: number): IFurnitureData; + getWallItemDataByName(name: string): IFurnitureData; + getProductData(type: string): IProductData; + getBadgeUrl(name: string): string; + getGroupBadgeUrl(name: string): string; + getBadgeImage(name: string): Texture; + loadBadgeImage(name: string): string; + getGroupBadgeImage(name: string): Texture; + loadGroupBadgeImage(name: string): string; + hasSecurity(level: number): boolean; + giveRespect(userId: number): void; + givePetRespect(petId: number): void; + sendSpecialCommandMessage(text: string, styleId?: number): void; + sendChatStyleUpdate(styleId: number): void; + ignoreUser(name: string): void; + unignoreUser(name: string): void; + isUserIgnored(name: string): boolean; + communication: INitroCommunicationManager; + userId: number; + userName: string; + figure: string; + gender: string; + isGodMode: boolean; + realName: string; + ignoredUsersManager: IgnoredUsersManager; + respectsReceived: number; + respectsLeft: number; + respectsPetLeft: number; + canChangeName: boolean; + clubLevel: number; + securityLevel: number; + isAmbassador: boolean; + isSystemOpen: boolean; + isSystemShutdown: boolean; + isAuthenticHabbo: boolean; + isModerator: boolean; + isCameraFollowDisabled: boolean; + chatStyle: number; + uiFlags: number; +} diff --git a/src/nitro/session/IgnoredUsersManager.ts b/src/nitro/session/IgnoredUsersManager.ts new file mode 100644 index 00000000..bb356045 --- /dev/null +++ b/src/nitro/session/IgnoredUsersManager.ts @@ -0,0 +1,130 @@ +import { IDisposable } from '../../core/common/disposable/IDisposable'; +import { IMessageEvent } from '../../core/communication/messages/IMessageEvent'; +import { IgnoredUsersEvent } from '../communication/messages/incoming/user/IgnoredUsersEvent'; +import { IgnoreResultEvent } from '../communication/messages/incoming/user/IgnoreResultEvent'; +import { GetIgnoredUsersComposer } from '../communication/messages/outgoing/user/data/GetIgnoredUsersComposer'; +import { IgnoreUserComposer } from '../communication/messages/outgoing/user/data/IgnoreUserComposer'; +import { IgnoreUserIdComposer } from '../communication/messages/outgoing/user/data/IgnoreUserIdComposer'; +import { UnignoreUserComposer } from '../communication/messages/outgoing/user/data/UnignoreUserComposer'; +import { SessionDataManager } from './SessionDataManager'; + +export class IgnoredUsersManager implements IDisposable +{ + private _sessionDataManager: SessionDataManager; + private _ignoredUsers: string[]; + + private _messages: IMessageEvent[]; + + constructor(sessionDataManager: SessionDataManager) + { + this._sessionDataManager = sessionDataManager; + this._ignoredUsers = []; + } + + public init(): void + { + if(this._sessionDataManager && this._sessionDataManager.communication) + { + this._messages = [ + new IgnoredUsersEvent(this.onIgnoredUsersEvent.bind(this)), + new IgnoreResultEvent(this.onIgnoreResultEvent.bind(this)) + ]; + + for(const message of this._messages) this._sessionDataManager.communication.registerMessageEvent(message); + } + } + + public dispose(): void + { + if(this.disposed) return; + + if(this._messages && this._messages.length) + { + for(const message of this._messages) this._sessionDataManager.communication.removeMessageEvent(message); + + this._messages = null; + } + + this._sessionDataManager = null; + } + + public requestIgnoredUsers(): void + { + this._sessionDataManager.send(new GetIgnoredUsersComposer(this._sessionDataManager.userName)); + } + + private onIgnoredUsersEvent(event: IgnoredUsersEvent): void + { + if(!event) return; + + const parser = event.getParser(); + + if(!parser) return; + + this._ignoredUsers = parser.ignoredUsers; + } + + private onIgnoreResultEvent(event: IgnoreResultEvent): void + { + if(!event) return; + + const parser = event.getParser(); + + if(!parser) return; + + const name = parser.name; + + switch(parser.result) + { + case 0: + return; + case 1: + this._Str_19721(name); + return; + case 2: + this._Str_19721(name); + this._ignoredUsers.shift(); + return; + case 3: + this._Str_23631(name); + return; + } + } + + private _Str_19721(name: string): void + { + if(this._ignoredUsers.indexOf(name) < 0) this._ignoredUsers.push(name); + } + + private _Str_23631(name: string): void + { + const index = this._ignoredUsers.indexOf(name); + + if(index >= 0) this._ignoredUsers.splice(index, 1); + } + + public ignoreUserId(id: number): void + { + this._sessionDataManager.send(new IgnoreUserIdComposer(id)); + } + + public ignoreUser(name: string): void + { + this._sessionDataManager.send(new IgnoreUserComposer(name)); + } + + public unignoreUser(name: string): void + { + this._sessionDataManager.send(new UnignoreUserComposer(name)); + } + + public isIgnored(name: string): boolean + { + return (this._ignoredUsers.indexOf(name) >= 0); + } + + public get disposed(): boolean + { + return !!this._sessionDataManager; + } +} diff --git a/src/nitro/session/RoomPetData.ts b/src/nitro/session/RoomPetData.ts new file mode 100644 index 00000000..f99550cc --- /dev/null +++ b/src/nitro/session/RoomPetData.ts @@ -0,0 +1,295 @@ +export class RoomPetData +{ + private _id: number; + private _level: number; + private _maximumLevel: number; + private _experience: number; + private _levelExperienceGoal: number; + private _energy: number; + private _maximumEnergy: number; + private _happyness: number; + private _maximumHappyness: number; + private _ownerId: number; + private _ownerName: string; + private _respect: number; + private _age: number; + private _unknownRarity: number; + private _saddle: boolean; + private _rider: boolean; + private _breedable: boolean; + private _Str_4460: number[]; + private _publiclyRideable: number; + private _fullyGrown: boolean; + private _dead: boolean; + private _maximumTimeToLive: number; + private _remainingTimeToLive: number; + private _remainingGrowTime: number; + private _rarityLevel: number; + private _publiclyBreedable: boolean; + private _Str_24910: number = 7; + + public get id(): number + { + return this._id; + } + + public set id(k: number) + { + this._id = k; + } + + public get level(): number + { + return this._level; + } + + public set level(level: number) + { + this._level = level; + } + + public get maximumLevel(): number + { + return this._maximumLevel; + } + + public set maximumLevel(k: number) + { + this._maximumLevel = k; + } + + public get experience(): number + { + return this._experience; + } + + public set experience(experience: number) + { + this._experience = experience; + } + + public get levelExperienceGoal(): number + { + return this._levelExperienceGoal; + } + + public set levelExperienceGoal(k: number) + { + this._levelExperienceGoal = k; + } + + public get energy(): number + { + return this._energy; + } + + public set energy(energy: number) + { + this._energy = energy; + } + + public get maximumEnergy(): number + { + return this._maximumEnergy; + } + + public set maximumEnergy(k: number) + { + this._maximumEnergy = k; + } + + public get happyness(): number + { + return this._happyness; + } + + public set happyness(k: number) + { + this._happyness = k; + } + + public get maximumHappyness(): number + { + return this._maximumHappyness; + } + + public set maximumHappyness(k: number) + { + this._maximumHappyness = k; + } + + public get ownerId(): number + { + return this._ownerId; + } + + public set ownerId(k: number) + { + this._ownerId = k; + } + + public get ownerName(): string + { + return this._ownerName; + } + + public set ownerName(ownerName: string) + { + this._ownerName = ownerName; + } + + public get respect(): number + { + return this._respect; + } + + public set respect(k: number) + { + this._respect = k; + } + + public get age(): number + { + return this._age; + } + + public set age(age: number) + { + this._age = age; + } + + public get unknownRarity(): number + { + return this._unknownRarity; + } + + public set unknownRarity(k: number) + { + this._unknownRarity = k; + } + + public get saddle(): boolean + { + return this._saddle; + } + + public set saddle(k: boolean) + { + this._saddle = k; + } + + public get rider(): boolean + { + return this._rider; + } + + public set rider(k: boolean) + { + this._rider = k; + } + + public get _Str_3307(): number[] + { + return this._Str_4460; + } + + public set _Str_3307(k: number[]) + { + this._Str_4460 = k; + } + + public get publiclyRideable(): number + { + return this._publiclyRideable; + } + + public set publiclyRideable(k: number) + { + this._publiclyRideable = k; + } + + public get breedable(): boolean + { + return this._breedable; + } + + public set breedable(k: boolean) + { + this._breedable = k; + } + + public get fullyGrown(): boolean + { + return this._fullyGrown; + } + + public set fullyGrown(k: boolean) + { + this._fullyGrown = k; + } + + public get dead(): boolean + { + return this._dead; + } + + public set dead(k: boolean) + { + this._dead = k; + } + + public get rarityLevel(): number + { + return this._rarityLevel; + } + + public set rarityLevel(rarityLevel: number) + { + this._rarityLevel = rarityLevel; + } + + public get maximumTimeToLive(): number + { + return this._maximumTimeToLive; + } + + public set maximumTimeToLive(k: number) + { + this._maximumTimeToLive = k; + } + + public get remainingTimeToLive(): number + { + return this._remainingTimeToLive; + } + + public set remainingTimeToLive(k: number) + { + this._remainingTimeToLive = k; + } + + public get remainingGrowTime(): number + { + return this._remainingGrowTime; + } + + public set remainingGrowTime(k: number) + { + this._remainingGrowTime = k; + } + + public get publiclyBreedable(): boolean + { + return this._publiclyBreedable; + } + + public set publiclyBreedable(k: boolean) + { + this._publiclyBreedable = k; + } + + public get _Str_20651(): number + { + return this._Str_24910; + } +} diff --git a/src/nitro/session/RoomSession.ts b/src/nitro/session/RoomSession.ts new file mode 100644 index 00000000..61d43077 --- /dev/null +++ b/src/nitro/session/RoomSession.ts @@ -0,0 +1,389 @@ +import { Disposable } from '../../core/common/disposable/Disposable'; +import { IConnection } from '../../core/communication/connections/IConnection'; +import { RoomDoorbellAccessComposer } from '../communication/messages/outgoing/room/access/RoomDoorbellAccessComposer'; +import { RoomEnterComposer } from '../communication/messages/outgoing/room/access/RoomEnterComposer'; +import { RoomAmbassadorAlertComposer } from '../communication/messages/outgoing/room/action/RoomAmbassadorAlertComposer'; +import { RoomBanUserComposer } from '../communication/messages/outgoing/room/action/RoomBanUserComposer'; +import { RoomGiveRightsComposer } from '../communication/messages/outgoing/room/action/RoomGiveRightsComposer'; +import { RoomKickUserComposer } from '../communication/messages/outgoing/room/action/RoomKickUserComposer'; +import { RoomMuteUserComposer } from '../communication/messages/outgoing/room/action/RoomMuteUserComposer'; +import { RoomTakeRightsComposer } from '../communication/messages/outgoing/room/action/RoomTakeRightsComposer'; +import { BotRemoveComposer } from '../communication/messages/outgoing/room/engine/BotRemoveComposer'; +import { PetRemoveComposer } from '../communication/messages/outgoing/room/engine/PetRemoveComposer'; +import { MoodlightSettingsComposer } from '../communication/messages/outgoing/room/furniture/dimmer/MoodlightSettingsComposer'; +import { MoodlightSettingsSaveComposer } from '../communication/messages/outgoing/room/furniture/dimmer/MoodlightSettingsSaveComposer'; +import { MoodlightTogggleStateComposer } from '../communication/messages/outgoing/room/furniture/dimmer/MoodlightTogggleStateComposer'; +import { OpenPresentComposer } from '../communication/messages/outgoing/room/furniture/presents/OpenPresentComposer'; +import { RoomUnitChatComposer } from '../communication/messages/outgoing/room/unit/chat/RoomUnitChatComposer'; +import { RoomUnitChatShoutComposer } from '../communication/messages/outgoing/room/unit/chat/RoomUnitChatShoutComposer'; +import { RoomUnitChatWhisperComposer } from '../communication/messages/outgoing/room/unit/chat/RoomUnitChatWhisperComposer'; +import { RoomUnitTypingStartComposer } from '../communication/messages/outgoing/room/unit/chat/RoomUnitTypingStartComposer'; +import { RoomUnitTypingStopComposer } from '../communication/messages/outgoing/room/unit/chat/RoomUnitTypingStopComposer'; +import { RoomUnitActionComposer } from '../communication/messages/outgoing/room/unit/RoomUnitActionComposer'; +import { RoomUnitDanceComposer } from '../communication/messages/outgoing/room/unit/RoomUnitDanceComposer'; +import { RoomUnitPostureComposer } from '../communication/messages/outgoing/room/unit/RoomUnitPostureComposer'; +import { RoomUnitSignComposer } from '../communication/messages/outgoing/room/unit/RoomUnitSignComposer'; +import { UserMottoComposer } from '../communication/messages/outgoing/user/data/UserMottoComposer'; +import { RoomModerationParser } from '../communication/messages/parser/room/data/RoomModerationParser'; +import { RoomControllerLevel } from './enum/RoomControllerLevel'; +import { RoomTradingLevelEnum } from './enum/RoomTradingLevelEnum'; +import { RoomSessionEvent } from './events/RoomSessionEvent'; +import { IRoomSession } from './IRoomSession'; +import { UserDataManager } from './UserDataManager'; + +export class RoomSession extends Disposable implements IRoomSession +{ + private _connection: IConnection; + private _userData: UserDataManager; + + private _roomId: number; + private _password: string; + private _state: string; + private _tradeMode: number; + private _doorMode: number; + private _allowPets: boolean; + private _controllerLevel: number; + private _ownRoomIndex: number; + private _isGuildRoom: boolean; + private _isRoomOwner: boolean; + private _isDecorating: boolean; + private _isSpectator: boolean; + + private _moderationSettings: RoomModerationParser; + + constructor() + { + super(); + + this._connection = null; + this._userData = new UserDataManager(); + + this._roomId = 0; + this._password = null; + this._state = RoomSessionEvent.CREATED; + this._tradeMode = RoomTradingLevelEnum._Str_12752; + this._doorMode = 0; + this._controllerLevel = RoomControllerLevel.NONE; + this._ownRoomIndex = -1; + this._isGuildRoom = false; + this._isRoomOwner = false; + this._isDecorating = false; + this._isSpectator = false; + + this._moderationSettings = null; + } + + protected onDispose(): void + { + if(this._userData) + { + this._userData.dispose(); + + this._userData = null; + } + + this._connection = null; + } + + public setConnection(connection: IConnection): void + { + if(this._connection || !connection) return; + + this._connection = connection; + + if(this._userData) this._userData.setConnection(connection); + } + + public setControllerLevel(level: number): void + { + if((level >= RoomControllerLevel.NONE) && (level <= RoomControllerLevel.MODERATOR)) + { + this._controllerLevel = level; + + return; + } + + this._controllerLevel = RoomControllerLevel.NONE; + } + + public setOwnRoomIndex(roomIndex: number): void + { + this._ownRoomIndex = roomIndex; + } + + public setRoomOwner(): void + { + this._isRoomOwner = true; + } + + public start(): boolean + { + if(this._state !== RoomSessionEvent.CREATED || !this._connection) return false; + + this._state = RoomSessionEvent.STARTED; + + return this.enterRoom(); + } + + private enterRoom(): boolean + { + if(!this._connection) return false; + + this._connection.send(new RoomEnterComposer(this._roomId, this._password)); + + return true; + } + + public reset(roomId: number): void + { + if(roomId === this._roomId) return; + + this._roomId = roomId; + } + + public sendChatMessage(text: string, styleId: number): void + { + this._connection.send(new RoomUnitChatComposer(text, styleId)); + } + + public sendShoutMessage(text: string, styleId: number): void + { + this._connection.send(new RoomUnitChatShoutComposer(text, styleId)); + } + + public sendWhisperMessage(recipientName: string, text: string, styleId: number): void + { + this._connection.send(new RoomUnitChatWhisperComposer(recipientName, text, styleId)); + } + + public sendChatTypingMessage(isTyping: boolean): void + { + if(isTyping) this._connection.send(new RoomUnitTypingStartComposer()); + else this._connection.send(new RoomUnitTypingStopComposer()); + } + + public sendMottoMessage(motto: string): void + { + this._connection.send(new UserMottoComposer(motto)); + } + + public sendDanceMessage(danceId: number): void + { + this._connection.send(new RoomUnitDanceComposer(danceId)); + } + + public sendExpressionMessage(expression: number): void + { + this._connection.send(new RoomUnitActionComposer(expression)); + } + + public sendSignMessage(sign: number): void + { + if((sign < 0) || (sign > 17)) return; + + this._connection.send(new RoomUnitSignComposer(sign)); + } + + public sendPostureMessage(posture: number): void + { + this._connection.send(new RoomUnitPostureComposer(posture)); + } + + public sendDoorbellApprovalMessage(userName: string, flag: boolean): void + { + this._connection.send(new RoomDoorbellAccessComposer(userName,flag)); + } + + public sendAmbassadorAlertMessage(userId: number): void + { + this._connection.send(new RoomAmbassadorAlertComposer(userId)); + } + + public sendKickMessage(userId: number): void + { + this._connection.send(new RoomKickUserComposer(userId)); + } + + public sendMuteMessage(userId: number, minutes: number): void + { + this._connection.send(new RoomMuteUserComposer(userId, minutes, this._roomId)); + } + + public sendBanMessage(userId: number, type: string): void + { + this._connection.send(new RoomBanUserComposer(userId, this._roomId, type)); + } + + public sendGiveRightsMessage(userId: number): void + { + this._connection.send(new RoomGiveRightsComposer(userId)); + } + + public sendTakeRightsMessage(userId: number): void + { + this._connection.send(new RoomTakeRightsComposer(userId)); + } + + public updateMoodlightData(id: number, _Str_24446: number, color: number, _Str_5123: number, apply: boolean): void + { + const local6 = '000000' + color.toString(16).toUpperCase(); + const local7 = '#' + local6.substring((local6.length - 6)); + this.connection.send(new MoodlightSettingsSaveComposer(id, _Str_24446, local7, _Str_5123, apply)); + } + + public toggleMoodlightState(): void + { + this.connection.send(new MoodlightTogggleStateComposer()); + } + + public pickupPet(id: number): void + { + if(!this._connection) return; + + this._connection.send(new PetRemoveComposer(id)); + } + + public pickupBot(id: number): void + { + if(!this._connection) return; + + this._connection.send(new BotRemoveComposer(id)); + } + + public requestMoodlightSettings(): void + { + if(!this._connection) return; + + this._connection.send(new MoodlightSettingsComposer()); + } + + public openGift(_Str_1577: number): void + { + this._connection.send(new OpenPresentComposer(_Str_1577)); + } + + public get connection(): IConnection + { + return this._connection; + } + + public get userDataManager(): UserDataManager + { + return this._userData; + } + + public get roomId(): number + { + return this._roomId; + } + + public set roomId(roomId: number) + { + this._roomId = roomId; + } + + public get password(): string + { + return this._password; + } + + public set password(password: string) + { + this._password = password; + } + + public get state(): string + { + return this._state; + } + + public get _Str_7411(): boolean + { + return true; + } + + public get tradeMode(): number + { + return this._tradeMode; + } + + public set tradeMode(mode: number) + { + this._tradeMode = mode; + } + + public get doorMode(): number + { + return this._doorMode; + } + + public set doorMode(mode: number) + { + this._doorMode = mode; + } + + public get allowPets(): boolean + { + return this._allowPets; + } + + public set allowPets(flag: boolean) + { + this._allowPets = flag; + } + + public get controllerLevel(): number + { + return this._controllerLevel; + } + + public get ownRoomIndex(): number + { + return this._ownRoomIndex; + } + + public get isGuildRoom(): boolean + { + return this._isGuildRoom; + } + + public set isGuildRoom(flag: boolean) + { + this._isGuildRoom = flag; + } + + public get isRoomOwner(): boolean + { + return this._isRoomOwner; + } + + public get isDecorating(): boolean + { + return this._isDecorating; + } + + public set isDecorating(flag: boolean) + { + this._isDecorating = flag; + } + + public get isSpectator(): boolean + { + return this._isSpectator; + } + + public set isSpectator(flag: boolean) + { + this._isSpectator = flag; + } + + public get moderationSettings(): RoomModerationParser + { + return this._moderationSettings; + } + + public set moderationSettings(parser: RoomModerationParser) + { + this._moderationSettings = parser; + } +} diff --git a/src/nitro/session/RoomSessionManager.ts b/src/nitro/session/RoomSessionManager.ts new file mode 100644 index 00000000..d1e54169 --- /dev/null +++ b/src/nitro/session/RoomSessionManager.ts @@ -0,0 +1,242 @@ +import { NitroManager } from '../../core/common/NitroManager'; +import { INitroCommunicationManager } from '../communication/INitroCommunicationManager'; +import { RoomEngineEvent } from '../room/events/RoomEngineEvent'; +import { IRoomEngine } from '../room/IRoomEngine'; +import { RoomSessionEvent } from './events/RoomSessionEvent'; +import { BaseHandler } from './handler/BaseHandler'; +import { GenericErrorHandler } from './handler/GenericErrorHandler'; +import { RoomChatHandler } from './handler/RoomChatHandler'; +import { RoomDataHandler } from './handler/RoomDataHandler'; +import { RoomDimmerPresetsHandler } from './handler/RoomDimmerPresetsHandler'; +import { RoomPermissionsHandler } from './handler/RoomPermissionsHandler'; +import { RoomPresentHandler } from './handler/RoomPresentHandler'; +import { RoomSessionHandler } from './handler/RoomSessionHandler'; +import { RoomUsersHandler } from './handler/RoomUsersHandler'; +import { IRoomHandlerListener } from './IRoomHandlerListener'; +import { IRoomSession } from './IRoomSession'; +import { IRoomSessionManager } from './IRoomSessionManager'; +import { RoomSession } from './RoomSession'; + +export class RoomSessionManager extends NitroManager implements IRoomSessionManager, IRoomHandlerListener +{ + private _communication: INitroCommunicationManager; + private _roomEngine: IRoomEngine; + + private _handlers: BaseHandler[]; + private _sessions: Map; + private _pendingSession: IRoomSession; + + private _sessionStarting: boolean; + private _viewerSession: IRoomSession; + + constructor(communication: INitroCommunicationManager, roomEngine: IRoomEngine) + { + super(); + + this._communication = communication; + this._roomEngine = roomEngine; + + this._handlers = []; + this._sessions = new Map(); + this._pendingSession = null; + + this._sessionStarting = false; + this._viewerSession = null; + + this.onRoomEngineEvent = this.onRoomEngineEvent.bind(this); + } + + protected onInit(): void + { + this.createHandlers(); + + this.processPendingSession(); + + this._roomEngine.events.addEventListener(RoomEngineEvent.ENGINE_INITIALIZED, this.onRoomEngineEvent); + } + + protected onDispose(): void + { + this._roomEngine.events.removeEventListener(RoomEngineEvent.ENGINE_INITIALIZED, this.onRoomEngineEvent); + + super.onDispose(); + } + + private createHandlers(): void + { + const connection = this._communication && this._communication.connection; + + if(!connection) return; + + this._handlers.push( + new RoomChatHandler(connection, this), + new RoomDataHandler(connection, this), + new RoomDimmerPresetsHandler(connection, this), + new RoomPermissionsHandler(connection, this), + new RoomSessionHandler(connection, this), + new RoomUsersHandler(connection, this), + new RoomPresentHandler(connection, this), + new GenericErrorHandler(connection, this), + ); + } + + private setHandlers(session: IRoomSession): void + { + if(!this._handlers || !this._handlers.length) return; + + for(const handler of this._handlers) + { + if(!handler) continue; + + handler.setRoomId(session.roomId); + } + } + + public onRoomEngineEvent(event: RoomEngineEvent): void + { + this.processPendingSession(); + } + + private processPendingSession(): void + { + if(!this._pendingSession || !this._roomEngine.ready) return; + + this.addSession(this._pendingSession); + + this._pendingSession = null; + } + + public getSession(id: number): IRoomSession + { + const existing = this._sessions.get(this.getRoomId(id)); + + if(!existing) return null; + + return existing; + } + + public createSession(roomId: number, password: string = null): boolean + { + const session = new RoomSession(); + + session.roomId = roomId; + session.password = password; + + return this.addSession(session); + } + + private addSession(roomSession: IRoomSession): boolean + { + if(!this._roomEngine.ready) + { + this._pendingSession = roomSession; + + return false; + } + + this._sessionStarting = true; + + if(this._sessions.get(this.getRoomId(roomSession.roomId))) + { + this.removeSession(roomSession.roomId, false); + } + + roomSession.setConnection(this._communication.connection); + + this._sessions.set(this.getRoomId(roomSession.roomId), roomSession); + + this.events.dispatchEvent(new RoomSessionEvent(RoomSessionEvent.CREATED, roomSession)); + + this._viewerSession = roomSession; + + this.startSession(this._viewerSession); + + return true; + } + + public startSession(session: IRoomSession): boolean + { + if(session.state === RoomSessionEvent.STARTED) return false; + + this._sessionStarting = false; + + if(!session.start()) + { + this.removeSession(session.roomId); + + return false; + } + + this.events.dispatchEvent(new RoomSessionEvent(RoomSessionEvent.STARTED, session)); + + this.setHandlers(session); + + return true; + } + + public removeSession(id: number, openLandingView: boolean = true): void + { + const session = this.getSession(id); + + if(!session) return; + + this._sessions.delete(this.getRoomId(id)); + + this.events.dispatchEvent(new RoomSessionEvent(RoomSessionEvent.ENDED, session, openLandingView)); + + session.dispose(); + } + + public sessionUpdate(id: number, type: string): void + { + const session = this.getSession(id); + + if(!session) return; + + switch(type) + { + case RoomSessionHandler.RS_CONNECTED: + return; + case RoomSessionHandler.RS_READY: + return; + case RoomSessionHandler.RS_DISCONNECTED: + this.removeSession(id); + return; + } + } + + public sessionReinitialize(fromRoomId: number, toRoomId: number): void + { + const existing = this.getSession(fromRoomId); + + if(!existing) return; + + this._sessions.delete(this.getRoomId(fromRoomId)); + + existing.reset(toRoomId); + + this._sessions.set(this.getRoomId(toRoomId), existing); + + this.setHandlers(existing); + } + + private getRoomId(id: number): string + { + return 'hard_coded_room_id'; + } + + public get communication(): INitroCommunicationManager + { + return this._communication; + } + + public get roomEngine(): IRoomEngine + { + return this._roomEngine; + } + + public get viewerSession(): IRoomSession + { + return this._viewerSession; + } +} diff --git a/src/nitro/session/RoomUserData.ts b/src/nitro/session/RoomUserData.ts new file mode 100644 index 00000000..1e854420 --- /dev/null +++ b/src/nitro/session/RoomUserData.ts @@ -0,0 +1,256 @@ +export class RoomUserData +{ + private _roomIndex: number = -1; + private _name: string = ''; + private _type: number = 0; + private _sex: string = ''; + private _figure: string = ''; + private _custom: string = ''; + private _activityPoints: number; + private _webID: number = 0; + private _groupID: string = ''; + private _groupStatus: number = 0; + private _groupName: string = ''; + private _ownerId: number = 0; + private _ownerName: string = ''; + private _petLevel: number = 0; + private _rarityLevel: number = 0; + private _hasSaddle: boolean; + private _isRiding: boolean; + private _canBreed: boolean; + private _canHarvest: boolean; + private _canRevive: boolean; + private _hasBreedingPermission: boolean; + private _botSkills: number[]; + private _Str_9831: boolean; + + constructor(k: number) + { + this._roomIndex = k; + } + + public get roomIndex(): number + { + return this._roomIndex; + } + + public get activityPoints(): number + { + return this._activityPoints; + } + + public set activityPoints(k: number) + { + this._activityPoints = k; + } + + public get name(): string + { + return this._name; + } + + public set name(k: string) + { + this._name = k; + } + + public get type(): number + { + return this._type; + } + + public set type(k: number) + { + this._type = k; + } + + public get sex(): string + { + return this._sex; + } + + public set sex(k: string) + { + this._sex = k; + } + + public get figure(): string + { + return this._figure; + } + + public set figure(k: string) + { + this._figure = k; + } + + public get custom(): string + { + return this._custom; + } + + public set custom(k: string) + { + this._custom = k; + } + + public get webID(): number + { + return this._webID; + } + + public set webID(k: number) + { + this._webID = k; + } + + public get guildId(): string + { + return this._groupID; + } + + public set guildId(k: string) + { + this._groupID = k; + } + + public get groupName(): string + { + return this._groupName; + } + + public set groupName(k: string) + { + this._groupName = k; + } + + public get groupStatus(): number + { + return this._groupStatus; + } + + public set groupStatus(k: number) + { + this._groupStatus = k; + } + + public get ownerId(): number + { + return this._ownerId; + } + + public set ownerId(k: number) + { + this._ownerId = k; + } + + public get ownerName(): string + { + return this._ownerName; + } + + public set ownerName(k: string) + { + this._ownerName = k; + } + + public get rarityLevel(): number + { + return this._rarityLevel; + } + + public set rarityLevel(k: number) + { + this._rarityLevel = k; + } + + public get hasSaddle(): boolean + { + return this._hasSaddle; + } + + public set hasSaddle(k: boolean) + { + this._hasSaddle = k; + } + + public get isRiding(): boolean + { + return this._isRiding; + } + + public set isRiding(k: boolean) + { + this._isRiding = k; + } + + public get canBreed(): boolean + { + return this._canBreed; + } + + public set canBreed(k: boolean) + { + this._canBreed = k; + } + + public get canHarvest(): boolean + { + return this._canHarvest; + } + + public set canHarvest(k: boolean) + { + this._canHarvest = k; + } + + public get canRevive(): boolean + { + return this._canRevive; + } + + public set canRevive(k: boolean) + { + this._canRevive = k; + } + + public get hasBreedingPermission(): boolean + { + return this._hasBreedingPermission; + } + + public set hasBreedingPermission(k: boolean) + { + this._hasBreedingPermission = k; + } + + public get petLevel(): number + { + return this._petLevel; + } + + public set petLevel(k: number) + { + this._petLevel = k; + } + + public get botSkills(): number[] + { + return this._botSkills; + } + + public set botSkills(k: number[]) + { + this._botSkills = k; + } + + public get isModerator(): boolean + { + return this._Str_9831; + } + + public set isModerator(k: boolean) + { + this._Str_9831 = k; + } +} \ No newline at end of file diff --git a/src/nitro/session/SessionDataManager.ts b/src/nitro/session/SessionDataManager.ts new file mode 100644 index 00000000..d24eb95b --- /dev/null +++ b/src/nitro/session/SessionDataManager.ts @@ -0,0 +1,647 @@ +import { Texture } from 'pixi.js'; +import { NitroManager } from '../../core/common/NitroManager'; +import { IMessageComposer } from '../../core/communication/messages/IMessageComposer'; +import { NitroEvent } from '../../core/events/NitroEvent'; +import { INitroCommunicationManager } from '../communication/INitroCommunicationManager'; +import { AvailabilityStatusMessageEvent } from '../communication/messages/incoming/availability/AvailabilityStatusMessageEvent'; +import { ChangeNameUpdateEvent } from '../communication/messages/incoming/avatar/ChangeNameUpdateEvent'; +import { RoomModelNameEvent } from '../communication/messages/incoming/room/mapping/RoomModelNameEvent'; +import { UserPermissionsEvent } from '../communication/messages/incoming/user/access/UserPermissionsEvent'; +import { UserFigureEvent } from '../communication/messages/incoming/user/data/UserFigureEvent'; +import { UserInfoEvent } from '../communication/messages/incoming/user/data/UserInfoEvent'; +import { UserNameChangeMessageEvent } from '../communication/messages/incoming/user/data/UserNameChangeMessageEvent'; +import { InClientLinkEvent } from '../communication/messages/incoming/user/InClientLinkEvent'; +import { PetRespectComposer } from '../communication/messages/outgoing/pet/PetRespectComposer'; +import { RoomUnitChatComposer } from '../communication/messages/outgoing/room/unit/chat/RoomUnitChatComposer'; +import { RoomUnitChatStyleComposer } from '../communication/messages/outgoing/room/unit/chat/RoomUnitChatStyleComposer'; +import { UserRespectComposer } from '../communication/messages/outgoing/user/UserRespectComposer'; +import { NitroSettingsEvent } from '../events/NitroSettingsEvent'; +import { Nitro } from '../Nitro'; +import { HabboWebTools } from '../utils/HabboWebTools'; +import { BadgeImageManager } from './BadgeImageManager'; +import { SecurityLevel } from './enum/SecurityLevel'; +import { SessionDataPreferencesEvent } from './events/SessionDataPreferencesEvent'; +import { UserNameUpdateEvent } from './events/UserNameUpdateEvent'; +import { FurnitureDataParser } from './furniture/FurnitureDataParser'; +import { IFurnitureData } from './furniture/IFurnitureData'; +import { IFurnitureDataListener } from './furniture/IFurnitureDataListener'; +import { IgnoredUsersManager } from './IgnoredUsersManager'; +import { ISessionDataManager } from './ISessionDataManager'; +import { IProductData } from './product/IProductData'; +import { IProductDataListener } from './product/IProductDataListener'; +import { ProductDataParser } from './product/ProductDataParser'; + +export class SessionDataManager extends NitroManager implements ISessionDataManager +{ + private _communication: INitroCommunicationManager; + + private _userId: number; + private _name: string; + private _figure: string; + private _gender: string; + private _realName: string; + private _respectsReceived: number; + private _respectsLeft: number; + private _respectsPetLeft: number; + private _canChangeName: boolean; + + private _ignoredUsersManager: IgnoredUsersManager; + + private _clubLevel: number; + private _securityLevel: number; + private _isAmbassador: boolean; + + private _systemOpen: boolean; + private _systemShutdown: boolean; + private _isAuthenticHabbo: boolean; + private _isRoomCameraFollowDisabled: boolean; + private _chatStyle: number; + private _uiFlags: number; + + private _floorItems: Map; + private _wallItems: Map; + private _products: Map; + private _furnitureData: FurnitureDataParser; + private _productData: ProductDataParser; + + private _furnitureReady: boolean; + private _productsReady: boolean; + private _furnitureListenersNotified: boolean; + private _pendingFurnitureListeners: IFurnitureDataListener[]; + private _pendingProductListeners: IProductDataListener[]; + + private _badgeImageManager: BadgeImageManager; + + constructor(communication: INitroCommunicationManager) + { + super(); + + this._communication = communication; + + this.resetUserInfo(); + + this._ignoredUsersManager = new IgnoredUsersManager(this); + + this._clubLevel = 0; + this._securityLevel = 0; + this._isAmbassador = false; + + this._systemOpen = false; + this._systemShutdown = false; + this._isAuthenticHabbo = false; + this._isRoomCameraFollowDisabled = false; + this._chatStyle = 0; + this._uiFlags = 0; + + this._floorItems = new Map(); + this._wallItems = new Map(); + this._products = new Map(); + this._furnitureData = null; + + this._furnitureReady = false; + this._productsReady = false; + this._furnitureListenersNotified = false; + this._pendingFurnitureListeners = []; + this._pendingProductListeners = []; + + this._badgeImageManager = null; + + this.onFurnitureDataReadyEvent = this.onFurnitureDataReadyEvent.bind(this); + this.onProductDataReadyEvent = this.onProductDataReadyEvent.bind(this); + this.onNitroSettingsEvent = this.onNitroSettingsEvent.bind(this); + } + + protected onInit(): void + { + this.loadFurnitureData(); + this.loadProductData(); + this.loadBadgeImageManager(); + + (this._ignoredUsersManager && this._ignoredUsersManager.init()); + + this._communication.registerMessageEvent(new UserFigureEvent(this.onUserFigureEvent.bind(this))); + this._communication.registerMessageEvent(new UserInfoEvent(this.onUserInfoEvent.bind(this))); + this._communication.registerMessageEvent(new UserPermissionsEvent(this.onUserPermissionsEvent.bind(this))); + this._communication.registerMessageEvent(new AvailabilityStatusMessageEvent(this.onAvailabilityStatusMessageEvent.bind(this))); + this._communication.registerMessageEvent(new ChangeNameUpdateEvent(this.onChangeNameUpdateEvent.bind(this))); + this._communication.registerMessageEvent(new UserNameChangeMessageEvent(this.onUserNameChangeMessageEvent.bind(this))); + this._communication.registerMessageEvent(new RoomModelNameEvent(this.onRoomModelNameEvent.bind(this))); + this._communication.registerMessageEvent(new InClientLinkEvent(this.onInClientLinkEvent.bind(this))); + + Nitro.instance.events.addEventListener(NitroSettingsEvent.SETTINGS_UPDATED, this.onNitroSettingsEvent); + } + + protected onDispose(): void + { + this.destroyFurnitureData(); + + if(this._ignoredUsersManager) + { + this._ignoredUsersManager.dispose(); + + this._ignoredUsersManager = null; + } + + Nitro.instance.events.removeEventListener(NitroSettingsEvent.SETTINGS_UPDATED, this.onNitroSettingsEvent); + + super.onDispose(); + } + + private resetUserInfo(): void + { + this._userId = 0; + this._name = null; + this._figure = null; + this._gender = null; + this._realName = null; + this._canChangeName = false; + } + + private loadFurnitureData(): void + { + this.destroyFurnitureData(); + + this._furnitureData = new FurnitureDataParser(this._floorItems, this._wallItems, Nitro.instance.localization); + + this._furnitureData.addEventListener(FurnitureDataParser.FURNITURE_DATA_READY, this.onFurnitureDataReadyEvent); + + this._furnitureData.loadFurnitureData(Nitro.instance.getConfiguration('furnidata.url')); + } + + private loadProductData(): void + { + this.destroyProductData(); + + this._productData = new ProductDataParser(this._products); + + this._productData.addEventListener(ProductDataParser.PDP_PRODUCT_DATA_READY, this.onProductDataReadyEvent); + + this._productData.loadProductData(Nitro.instance.getConfiguration('productdata.url')); + } + + private loadBadgeImageManager(): void + { + if(this._badgeImageManager) return; + + this._badgeImageManager = new BadgeImageManager(Nitro.instance.core.asset, this.events); + } + + public hasProductData(listener: IProductDataListener): boolean + { + if(this._productsReady) return true; + + if(listener && (this._pendingProductListeners.indexOf(listener) === -1)) this._pendingProductListeners.push(listener); + + return false; + } + + public getAllFurnitureData(listener: IFurnitureDataListener): IFurnitureData[] + { + if(!this._furnitureReady) + { + if(this._pendingFurnitureListeners.indexOf(listener) === -1) this._pendingFurnitureListeners.push(listener); + + return null; + } + + const furnitureData: IFurnitureData[] = []; + + for(const data of this._floorItems.values()) + { + if(!data) continue; + + furnitureData.push(data); + } + + for(const data of this._wallItems.values()) + { + if(!data) continue; + + furnitureData.push(data); + } + + if(!furnitureData || !furnitureData.length) return null; + + return furnitureData; + } + + public removePendingFurniDataListener(listener: IFurnitureDataListener): void + { + if(!this._pendingFurnitureListeners) return; + + const index = this._pendingFurnitureListeners.indexOf(listener); + + if(index === -1) return; + + this._pendingFurnitureListeners.splice(index, 1); + } + + private onUserFigureEvent(event: UserFigureEvent): void + { + if(!event || !event.connection) return; + + this._figure = event.getParser().figure; + this._gender = event.getParser().gender; + + HabboWebTools.updateFigure(this._figure); + } + + private onUserInfoEvent(event: UserInfoEvent): void + { + if(!event || !event.connection) return; + + this.resetUserInfo(); + + const userInfo = event.getParser().userInfo; + + if(!userInfo) return; + + this._userId = userInfo.userId; + this._name = userInfo.username; + this._figure = userInfo.figure; + this._gender = userInfo.gender; + this._realName = userInfo.realName; + this._respectsReceived = userInfo.respectsReceived; + this._respectsLeft = userInfo.respectsRemaining; + this._respectsPetLeft = userInfo.respectsPetRemaining; + this._canChangeName = userInfo.canChangeName; + + (this._ignoredUsersManager && this._ignoredUsersManager.requestIgnoredUsers()); + } + + private onUserPermissionsEvent(event: UserPermissionsEvent): void + { + if(!event || !event.connection) return; + + this._clubLevel = event.getParser().clubLevel; + this._securityLevel = event.getParser().securityLevel; + this._isAmbassador = event.getParser().isAmbassador; + } + + private onAvailabilityStatusMessageEvent(event: AvailabilityStatusMessageEvent): void + { + if(!event || !event.connection) return; + + const parser = event.getParser(); + + if(!parser) return; + + this._systemOpen = parser.isOpen; + this._systemShutdown = parser.onShutdown; + this._isAuthenticHabbo = parser.isAuthenticUser; + } + + private onChangeNameUpdateEvent(event: ChangeNameUpdateEvent): void + { + if(!event || !event.connection) return; + + const parser = event.getParser(); + + if(!parser) return; + + if(parser.resultCode !== ChangeNameUpdateEvent._Str_5797) return; + + this._canChangeName = false; + + this.events.dispatchEvent(new UserNameUpdateEvent(parser.name)); + } + + private onUserNameChangeMessageEvent(event: UserNameChangeMessageEvent): void + { + if(!event || !event.connection) return; + + const parser = event.getParser(); + + if(!parser) return; + + if(parser.webId !== this.userId) return; + + this._name = parser.newName; + this._canChangeName = false; + + this.events.dispatchEvent(new UserNameUpdateEvent(this._name)); + } + + private onRoomModelNameEvent(event: RoomModelNameEvent): void + { + if(!event) return; + + const parser = event.getParser(); + + if(!parser) return; + + HabboWebTools.roomVisited(parser.roomId); + } + + private onFurnitureDataReadyEvent(event: NitroEvent): void + { + this._furnitureData.removeEventListener(FurnitureDataParser.FURNITURE_DATA_READY, this.onFurnitureDataReadyEvent); + + this._furnitureReady = true; + + if(!this._furnitureListenersNotified) + { + this._furnitureListenersNotified = true; + + if(this._pendingFurnitureListeners && this._pendingFurnitureListeners.length) + { + for(const listener of this._pendingFurnitureListeners) listener && listener.loadFurnitureData(); + } + } + + this._pendingProductListeners = []; + } + + private onProductDataReadyEvent(event: NitroEvent): void + { + this._productData.removeEventListener(ProductDataParser.PDP_PRODUCT_DATA_READY, this.onProductDataReadyEvent); + + this._productsReady = true; + + for(const listener of this._pendingProductListeners) listener && listener.loadProductData(); + + this._pendingProductListeners = []; + } + + private onInClientLinkEvent(event: InClientLinkEvent):void + { + if(!event) return; + + const parser = event.getParser(); + + if(!parser) return; + + Nitro.instance.createLinkEvent(parser.link); + } + + private onNitroSettingsEvent(event: NitroSettingsEvent): void + { + this._isRoomCameraFollowDisabled = event.cameraFollow; + this._chatStyle = event.chatType; + this._uiFlags = event.flags; + + this.events.dispatchEvent(new SessionDataPreferencesEvent(this._uiFlags)); + } + + private destroyFurnitureData(): void + { + if(!this._furnitureData) return; + + this._furnitureData.dispose(); + + this._furnitureData = null; + } + + private destroyProductData(): void + { + if(!this._productData) return; + + this._productData.dispose(); + + this._productData = null; + } + + public getFloorItemData(id: number): IFurnitureData + { + const existing = this._floorItems.get(id); + + if(!existing) return null; + + return existing; + } + + public getFloorItemDataByName(name: string): IFurnitureData + { + if(!name || !this._floorItems || !this._floorItems.size) return null; + + for(const item of this._floorItems.values()) + { + if(!item || (item.className !== name)) continue; + + return item; + } + } + + public getWallItemData(id: number): IFurnitureData + { + const existing = this._wallItems.get(id); + + if(!existing) return null; + + return existing; + } + + public getWallItemDataByName(name: string): IFurnitureData + { + if(!name || !this._wallItems || !this._wallItems.size) return null; + + for(const item of this._wallItems.values()) + { + if(!item || (item.className !== name)) continue; + + return item; + } + } + + public getProductData(type: string): IProductData + { + if(!this._productsReady) this.loadProductData(); + + return this._products.get(type); + } + + public getBadgeUrl(name: string): string + { + return this._badgeImageManager.getBadgeUrl(name); + } + + public getGroupBadgeUrl(name: string): string + { + return this._badgeImageManager.getBadgeUrl(name, BadgeImageManager.GROUP_BADGE); + } + + public getBadgeImage(name: string): Texture + { + return this._badgeImageManager.getBadgeImage(name); + } + + public getGroupBadgeImage(name: string): Texture + { + return this._badgeImageManager.getBadgeImage(name, BadgeImageManager.GROUP_BADGE); + } + + public loadBadgeImage(name: string): string + { + return this._badgeImageManager.loadBadgeImage(name); + } + + public loadGroupBadgeImage(name: string): string + { + return this._badgeImageManager.loadBadgeImage(name, BadgeImageManager.GROUP_BADGE); + } + + public hasSecurity(level: number): boolean + { + return this._securityLevel >= level; + } + + public giveRespect(userId: number): void + { + if((userId < 0) || (this._respectsLeft <= 0)) return; + + this.send(new UserRespectComposer(userId)); + + this._respectsLeft--; + } + + public givePetRespect(petId: number): void + { + if((petId < 0) || (this._respectsPetLeft <= 0)) return; + + this.send(new PetRespectComposer(petId)); + + this._respectsPetLeft--; + } + + public sendSpecialCommandMessage(text: string, styleId: number = 0): void + { + this.send(new RoomUnitChatComposer(text)); + } + + public sendChatStyleUpdate(styleId: number): void + { + this._chatStyle = styleId; + + this.send(new RoomUnitChatStyleComposer(styleId)); + } + + public ignoreUser(name: string): void + { + (this._ignoredUsersManager && this._ignoredUsersManager.ignoreUser(name)); + } + + public unignoreUser(name: string): void + { + (this._ignoredUsersManager && this._ignoredUsersManager.unignoreUser(name)); + } + + public isUserIgnored(name: string): boolean + { + return (this._ignoredUsersManager && this._ignoredUsersManager.isIgnored(name)); + } + + public send(composer: IMessageComposer): void + { + this._communication.connection.send(composer); + } + + public get communication(): INitroCommunicationManager + { + return this._communication; + } + + public get userId(): number + { + return this._userId; + } + + public get userName(): string + { + return this._name; + } + + public get figure(): string + { + return this._figure; + } + + public get gender(): string + { + return this._gender; + } + + public get realName(): string + { + return this._realName; + } + + public get ignoredUsersManager(): IgnoredUsersManager + { + return this._ignoredUsersManager; + } + + public get respectsReceived(): number + { + return this._respectsReceived; + } + + public get respectsLeft(): number + { + return this._respectsLeft; + } + + public get respectsPetLeft(): number + { + return this._respectsPetLeft; + } + + public get canChangeName(): boolean + { + return this._canChangeName; + } + + public get clubLevel(): number + { + return this._clubLevel; + } + + public get securityLevel(): number + { + return this._securityLevel; + } + + public get isAmbassador(): boolean + { + return this._isAmbassador; + } + + public get isSystemOpen(): boolean + { + return this._systemOpen; + } + + public get isSystemShutdown(): boolean + { + return this._systemShutdown; + } + + public get isAuthenticHabbo(): boolean + { + return this._isAuthenticHabbo; + } + + public get isModerator(): boolean + { + return (this._securityLevel >= SecurityLevel.MODERATOR); + } + + public get isGodMode(): boolean + { + return this.securityLevel >= SecurityLevel.MODERATOR; + } + + public get isCameraFollowDisabled(): boolean + { + return this._isRoomCameraFollowDisabled; + } + + public get chatStyle(): number + { + return this._chatStyle; + } + + public get uiFlags(): number + { + return this._uiFlags; + } +} diff --git a/src/nitro/session/UserDataManager.ts b/src/nitro/session/UserDataManager.ts new file mode 100644 index 00000000..9b581610 --- /dev/null +++ b/src/nitro/session/UserDataManager.ts @@ -0,0 +1,192 @@ +import { Disposable } from '../../core/common/disposable/Disposable'; +import { IConnection } from '../../core/communication/connections/IConnection'; +import { RequestPetInfoComposer } from '../communication/messages/outgoing/pet/RequestPetInfoComposer'; +import { UserCurrentBadgesComposer } from '../communication/messages/outgoing/user/data/UserCurrentBadgesComposer'; +import { RoomUserData } from './RoomUserData'; + +export class UserDataManager extends Disposable +{ + private static TYPE_USER: number = 1; + private static TYPE_PET: number = 2; + private static TYPE_BOT: number = 3; + private static TYPE_RENTABLE_BOT: number = 4; + + private _connection: IConnection; + + private _userDataByType: Map>; + private _userDataByRoomIndex: Map; + private _userBadges: Map; + + constructor() + { + super(); + + this._connection = null; + + this._userDataByType = new Map(); + this._userDataByRoomIndex = new Map(); + this._userBadges = new Map(); + } + + protected onDispose(): void + { + this._connection = null; + } + + public setConnection(connection: IConnection): void + { + this._connection = connection; + } + + public getUserData(webID: number): RoomUserData + { + return this.getDataByType(webID, UserDataManager.TYPE_USER); + } + + public getPetData(webID: number): RoomUserData + { + return this.getDataByType(webID, UserDataManager.TYPE_PET); + } + + public getBotData(webID: number): RoomUserData + { + return this.getDataByType(webID, UserDataManager.TYPE_BOT); + } + + public getRentableBotData(webID: number): RoomUserData + { + return this.getDataByType(webID, UserDataManager.TYPE_RENTABLE_BOT); + } + + public getDataByType(webID: number, type: number): RoomUserData + { + const existing = this._userDataByType.get(type); + + if(!existing) return null; + + const userData = existing.get(webID); + + if(!userData) return null; + + return userData; + } + + public getUserDataByIndex(roomIndex: number): RoomUserData + { + const existing = this._userDataByRoomIndex.get(roomIndex); + + if(!existing) return null; + + return existing; + } + + public getUserDataByName(name: string): RoomUserData + { + for(const userData of this._userDataByRoomIndex.values()) + { + if(!userData || (userData.name !== name)) continue; + + return userData; + } + + return null; + } + + public updateUserData(data: RoomUserData): void + { + if(!data) return; + + this.removeUserData(data.roomIndex); + + let existingType = this._userDataByType.get(data.type); + + if(!existingType) + { + existingType = new Map(); + + this._userDataByType.set(data.type, existingType); + } + + existingType.set(data.webID, data); + + this._userDataByRoomIndex.set(data.roomIndex, data); + } + + public removeUserData(roomIndex: number): void + { + const existing = this.getUserDataByIndex(roomIndex); + + if(!existing) return; + + this._userDataByRoomIndex.delete(roomIndex); + + const existingType = this._userDataByType.get(existing.type); + + if(existingType) existingType.delete(existing.webID); + } + + public getUserBadges(userId: number): string[] + { + if(this._connection) + { + this._connection.send(new UserCurrentBadgesComposer(userId)); + } + + const badges = this._userBadges.get(userId); + + if(!badges) return []; + + return badges; + } + + public setUserBadges(userId: number, badges: string[]): void + { + this._userBadges.set(userId, badges); + } + + public updateFigure(roomIndex: number, figure: string, sex: string, hasSaddle: boolean, isRiding: boolean): void + { + const userData = this.getUserDataByIndex(roomIndex); + + if(!userData) return; + + userData.figure = figure; + userData.sex = sex; + userData.hasSaddle = hasSaddle; + userData.isRiding = isRiding; + } + + public updateName(roomIndex: number, name: string): void + { + const userData = this.getUserDataByIndex(roomIndex); + + if(!userData) return; + + userData.name = name; + } + + public updateMotto(roomIndex: number, custom: string): void + { + const userData = this.getUserDataByIndex(roomIndex); + + if(!userData) return; + + userData.custom = custom; + } + + public requestPetInfo(id: number): void + { + if(!this._connection) return; + + const petData = this.getPetData(id); + + if(!petData) return; + + this._connection.send(new RequestPetInfoComposer(id)); + } + + public get connection(): IConnection + { + return this._connection; + } +} diff --git a/src/nitro/session/enum/GenericErrorEnum.ts b/src/nitro/session/enum/GenericErrorEnum.ts new file mode 100644 index 00000000..8b16e148 --- /dev/null +++ b/src/nitro/session/enum/GenericErrorEnum.ts @@ -0,0 +1,5 @@ +export class GenericErrorEnum +{ + public static KICKED_OUT_OF_ROOM: number = 4008; + public static _Str_19451: number = -13001; +} diff --git a/src/nitro/session/enum/RoomControllerLevel.ts b/src/nitro/session/enum/RoomControllerLevel.ts new file mode 100644 index 00000000..9f45bc6e --- /dev/null +++ b/src/nitro/session/enum/RoomControllerLevel.ts @@ -0,0 +1,9 @@ +export class RoomControllerLevel +{ + public static NONE: number = 0; + public static GUEST: number = 1; + public static GUILD_MEMBER: number = 2; + public static GUILD_ADMIN: number = 3; + public static ROOM_OWNER: number = 4; + public static MODERATOR: number = 5; +} \ No newline at end of file diff --git a/src/nitro/session/enum/RoomTradingLevelEnum.ts b/src/nitro/session/enum/RoomTradingLevelEnum.ts new file mode 100644 index 00000000..d4b73ad5 --- /dev/null +++ b/src/nitro/session/enum/RoomTradingLevelEnum.ts @@ -0,0 +1,22 @@ +export class RoomTradingLevelEnum +{ + public static _Str_12752: number = 0; + public static _Str_14475: number = 1; + public static _Str_9173: number = 2; + + + public static _Str_22614(k: number): string + { + switch(k) + { + case RoomTradingLevelEnum._Str_9173: + return '${trading.mode.free}'; + case RoomTradingLevelEnum._Str_14475: + return '${trading.mode.controller}'; + case RoomTradingLevelEnum._Str_12752: + return '${trading.mode.not.allowed}'; + } + + return ''; + } +} \ No newline at end of file diff --git a/src/nitro/session/enum/SecurityLevel.ts b/src/nitro/session/enum/SecurityLevel.ts new file mode 100644 index 00000000..4f9b6934 --- /dev/null +++ b/src/nitro/session/enum/SecurityLevel.ts @@ -0,0 +1,13 @@ +export class SecurityLevel +{ + public static SUPER_USER: number = 9; + public static ADMINISTRATOR: number = 8; + public static COMMUNITY: number = 7; + public static PLAYER_SUPPORT: number = 6; + public static MODERATOR: number = 5; + public static EMPLOYEE: number = 4; + public static BUS_PARTNER: number = 3; + public static PARTNER: number = 2; + public static CELEBRITY: number = 1; + public static NONE: number = 0; +} \ No newline at end of file diff --git a/src/nitro/session/events/BadgeImageReadyEvent.ts b/src/nitro/session/events/BadgeImageReadyEvent.ts new file mode 100644 index 00000000..b7418010 --- /dev/null +++ b/src/nitro/session/events/BadgeImageReadyEvent.ts @@ -0,0 +1,28 @@ +import { Texture } from 'pixi.js'; +import { NitroEvent } from '../../../core/events/NitroEvent'; + +export class BadgeImageReadyEvent extends NitroEvent +{ + public static IMAGE_READY: string = 'BIME_BADGE_IMAGE_READY'; + + private _badgeId: string; + private _image: Texture; + + constructor(badgeId: string, image: Texture) + { + super(BadgeImageReadyEvent.IMAGE_READY); + + this._badgeId = badgeId; + this._image = image; + } + + public get badgeId(): string + { + return this._badgeId; + } + + public get image(): Texture + { + return this._image; + } +} \ No newline at end of file diff --git a/src/nitro/session/events/MysteryBoxKeysUpdateEvent.ts b/src/nitro/session/events/MysteryBoxKeysUpdateEvent.ts new file mode 100644 index 00000000..fd7e5bc6 --- /dev/null +++ b/src/nitro/session/events/MysteryBoxKeysUpdateEvent.ts @@ -0,0 +1,27 @@ +import { NitroEvent } from '../../../core/events/NitroEvent'; + +export class MysteryBoxKeysUpdateEvent extends NitroEvent +{ + public static MBKE_UPDATE: string = 'mbke_update'; + + private _boxColor: string; + private _keyColor: string; + + constructor(k: string, _arg_2: string) + { + super(MysteryBoxKeysUpdateEvent.MBKE_UPDATE); + + this._boxColor = k; + this._keyColor = _arg_2; + } + + public get _Str_18286(): string + { + return this._boxColor; + } + + public get _Str_17811(): string + { + return this._keyColor; + } +} \ No newline at end of file diff --git a/src/nitro/session/events/PerksUpdatedEvent.ts b/src/nitro/session/events/PerksUpdatedEvent.ts new file mode 100644 index 00000000..6bc421e4 --- /dev/null +++ b/src/nitro/session/events/PerksUpdatedEvent.ts @@ -0,0 +1,11 @@ +import { NitroEvent } from '../../../core/events/NitroEvent'; + +export class PerksUpdatedEvent extends NitroEvent +{ + public static PERKS_UPDATED: string = 'PUE_perks_updated'; + + constructor() + { + super(PerksUpdatedEvent.PERKS_UPDATED); + } +} \ No newline at end of file diff --git a/src/nitro/session/events/RoomSessionChatEvent.ts b/src/nitro/session/events/RoomSessionChatEvent.ts new file mode 100644 index 00000000..3254262f --- /dev/null +++ b/src/nitro/session/events/RoomSessionChatEvent.ts @@ -0,0 +1,69 @@ +import { IRoomSession } from '../IRoomSession'; +import { RoomSessionEvent } from './RoomSessionEvent'; + +export class RoomSessionChatEvent extends RoomSessionEvent +{ + public static CHAT_EVENT: string = 'RSCE_CHAT_EVENT'; + public static FLOOD_EVENT: string = 'RSCE_FLOOD_EVENT'; + + public static CHAT_NORMAL: number = 0; + public static CHAT_WHISPER: number = 1; + public static CHAT_SHOUT: number = 2; + public static _Str_5821: number = 3; + public static _Str_6081: number = 4; + public static _Str_8971: number = 5; + public static _Str_5958: number = 6; + public static _Str_6065: number = 7; + public static _Str_5998: number = 8; + public static _Str_5904: number = 9; + public static _Str_8909: number = 10; + + private _objectId: number; + private _message: string; + private _chatType: number; + private _links: string[]; + private _extraParam: number; + private _style: number; + + constructor(type: string, session: IRoomSession, objectId: number, message: string, chatType: number, style: number = 0, links: string[] = null, extraParam: number = -1) + { + super(type, session); + + this._objectId = objectId; + this._message = message; + this._chatType = chatType; + this._links = links; + this._extraParam = extraParam; + this._style = style; + } + + public get objectId(): number + { + return this._objectId; + } + + public get message(): string + { + return this._message; + } + + public get chatType(): number + { + return this._chatType; + } + + public get links(): string[] + { + return this._links; + } + + public get extraParam(): number + { + return this._extraParam; + } + + public get style(): number + { + return this._style; + } +} \ No newline at end of file diff --git a/src/nitro/session/events/RoomSessionConfirmPetBreedingEvent.ts b/src/nitro/session/events/RoomSessionConfirmPetBreedingEvent.ts new file mode 100644 index 00000000..26eb1ce6 --- /dev/null +++ b/src/nitro/session/events/RoomSessionConfirmPetBreedingEvent.ts @@ -0,0 +1,49 @@ +import { IRoomSession } from '../IRoomSession'; +import { RoomSessionEvent } from './RoomSessionEvent'; + +export class RoomSessionConfirmPetBreedingEvent extends RoomSessionEvent +{ + public static RSPFUE_CONFIRM_PET_BREEDING: string = 'RSPFUE_CONFIRM_PET_BREEDING'; + + private _Str_5743: number; + private _pet1: any; + private _pet2: any; + private _Str_4447: any[]; + private _Str_6321: number; + + constructor(k: IRoomSession, _arg_2: number, _arg_3: any, _arg_4: any, _arg_5: any[], _arg_6: number) + { + super(RoomSessionConfirmPetBreedingEvent.RSPFUE_CONFIRM_PET_BREEDING, k); + + this._Str_5743 = _arg_2; + this._pet1 = _arg_3; + this._pet2 = _arg_4; + this._Str_4447 = _arg_5; + this._Str_6321 = _arg_6; + } + + public get _Str_10346(): any[] + { + return this._Str_4447; + } + + public get _Str_12369(): number + { + return this._Str_5743; + } + + public get pet1(): any + { + return this._pet1; + } + + public get pet2(): any + { + return this._pet2; + } + + public get _Str_16867(): number + { + return this._Str_6321; + } +} \ No newline at end of file diff --git a/src/nitro/session/events/RoomSessionConfirmPetBreedingResultEvent.ts b/src/nitro/session/events/RoomSessionConfirmPetBreedingResultEvent.ts new file mode 100644 index 00000000..b702457b --- /dev/null +++ b/src/nitro/session/events/RoomSessionConfirmPetBreedingResultEvent.ts @@ -0,0 +1,28 @@ +import { IRoomSession } from '../IRoomSession'; +import { RoomSessionEvent } from './RoomSessionEvent'; + +export class RoomSessionConfirmPetBreedingResultEvent extends RoomSessionEvent +{ + public static RSPFUE_CONFIRM_PET_BREEDING_RESULT: string = 'RSPFUE_CONFIRM_PET_BREEDING_RESULT'; + + private _breedingNestStuffId: number; + private _result: number; + + constructor(k: IRoomSession, _arg_2: number, _arg_3: number) + { + super(RoomSessionConfirmPetBreedingResultEvent.RSPFUE_CONFIRM_PET_BREEDING_RESULT, k); + + this._breedingNestStuffId = _arg_2; + this._result = _arg_3; + } + + public get _Str_12769(): number + { + return this._breedingNestStuffId; + } + + public get result(): number + { + return this._result; + } +} \ No newline at end of file diff --git a/src/nitro/session/events/RoomSessionDanceEvent.ts b/src/nitro/session/events/RoomSessionDanceEvent.ts new file mode 100644 index 00000000..16260185 --- /dev/null +++ b/src/nitro/session/events/RoomSessionDanceEvent.ts @@ -0,0 +1,28 @@ +import { IRoomSession } from '../IRoomSession'; +import { RoomSessionEvent } from './RoomSessionEvent'; + +export class RoomSessionDanceEvent extends RoomSessionEvent +{ + public static RSDE_DANCE: string = 'RSDE_DANCE'; + + private _roomIndex: number; + private _danceId: number; + + constructor(session: IRoomSession, roomIndex: number, danceId: number) + { + super(RoomSessionDanceEvent.RSDE_DANCE, session); + + this._roomIndex = roomIndex; + this._danceId = danceId; + } + + public get roomIndex(): number + { + return this._roomIndex; + } + + public get danceId(): number + { + return this._danceId; + } +} \ No newline at end of file diff --git a/src/nitro/session/events/RoomSessionDimmerPresetsEvent.ts b/src/nitro/session/events/RoomSessionDimmerPresetsEvent.ts new file mode 100644 index 00000000..dbeb0751 --- /dev/null +++ b/src/nitro/session/events/RoomSessionDimmerPresetsEvent.ts @@ -0,0 +1,48 @@ +import { IRoomSession } from '../IRoomSession'; +import { RoomSessionDimmerPresetsEventPresetItem } from './RoomSessionDimmerPresetsEventPresetItem'; +import { RoomSessionEvent } from './RoomSessionEvent'; + +export class RoomSessionDimmerPresetsEvent extends RoomSessionEvent +{ + public static RSDPE_PRESETS: string = 'RSDPE_PRESETS'; + + private _selectedPresetId: number = 0; + private _presets: RoomSessionDimmerPresetsEventPresetItem[]; + + constructor(k: string, _arg_2: IRoomSession) + { + super(k, _arg_2); + + this._presets = []; + } + + public get _Str_10888(): number + { + return this._presets.length; + } + + public get selectedPresetId(): number + { + return this._selectedPresetId; + } + + public set selectedPresetId(k: number) + { + this._selectedPresetId = k; + } + + public _Str_17287(k: number, _arg_2: number, _arg_3: number, _arg_4: number): void + { + const _local_5:RoomSessionDimmerPresetsEventPresetItem = new RoomSessionDimmerPresetsEventPresetItem(k, _arg_2, _arg_3, _arg_4); + this._presets[(k - 1)] = _local_5; + } + + public _Str_14989(k: number):RoomSessionDimmerPresetsEventPresetItem + { + if(((k < 0) || (k >= this._presets.length))) + { + return null; + } + return this._presets[k]; + } +} diff --git a/src/nitro/session/events/RoomSessionDimmerPresetsEventPresetItem.ts b/src/nitro/session/events/RoomSessionDimmerPresetsEventPresetItem.ts new file mode 100644 index 00000000..e52afad2 --- /dev/null +++ b/src/nitro/session/events/RoomSessionDimmerPresetsEventPresetItem.ts @@ -0,0 +1,35 @@ +export class RoomSessionDimmerPresetsEventPresetItem +{ + private _id: number; + private _type: number; + private _color: number; + private _light: number; + + constructor(k: number, _arg_2: number, _arg_3: number, _arg_4: number) + { + this._id = k; + this._type = _arg_2; + this._color = _arg_3; + this._light = _arg_4; + } + + public get id(): number + { + return this._id; + } + + public get type(): number + { + return this._type; + } + + public get color(): number + { + return this._color; + } + + public get _Str_4272(): number + { + return this._light; + } +} \ No newline at end of file diff --git a/src/nitro/session/events/RoomSessionDoorbellEvent.ts b/src/nitro/session/events/RoomSessionDoorbellEvent.ts new file mode 100644 index 00000000..fde5de07 --- /dev/null +++ b/src/nitro/session/events/RoomSessionDoorbellEvent.ts @@ -0,0 +1,23 @@ +import { IRoomSession } from '../IRoomSession'; +import { RoomSessionEvent } from './RoomSessionEvent'; + +export class RoomSessionDoorbellEvent extends RoomSessionEvent +{ + public static DOORBELL: string = 'RSDE_DOORBELL'; + public static RSDE_REJECTED: string = 'RSDE_REJECTED'; + public static RSDE_ACCEPTED: string = 'RSDE_ACCEPTED'; + + private _userName: string = ''; + + constructor(type: string, session: IRoomSession, userName: string) + { + super(type, session); + + this._userName = userName; + } + + public get userName(): string + { + return this._userName; + } +} \ No newline at end of file diff --git a/src/nitro/session/events/RoomSessionErrorMessageEvent.ts b/src/nitro/session/events/RoomSessionErrorMessageEvent.ts new file mode 100644 index 00000000..fb1fb7ce --- /dev/null +++ b/src/nitro/session/events/RoomSessionErrorMessageEvent.ts @@ -0,0 +1,32 @@ +import { IRoomSession } from '../IRoomSession'; +import { RoomSessionEvent } from './RoomSessionEvent'; + +export class RoomSessionErrorMessageEvent extends RoomSessionEvent +{ + public static RSEME_KICKED: string = 'RSEME_KICKED'; + public static RSEME_PETS_FORBIDDEN_IN_HOTEL: string = 'RSEME_PETS_FORBIDDEN_IN_HOTEL'; + public static RSEME_PETS_FORBIDDEN_IN_FLAT: string = 'RSEME_PETS_FORBIDDEN_IN_FLAT'; + public static RSEME_MAX_PETS: string = 'RSEME_MAX_PETS'; + public static RSEME_MAX_NUMBER_OF_OWN_PETS: string = 'RSEME_MAX_NUMBER_OF_OWN_PETS'; + public static RSEME_NO_FREE_TILES_FOR_PET: string = 'RSEME_NO_FREE_TILES_FOR_PET'; + public static RSEME_SELECTED_TILE_NOT_FREE_FOR_PET: string = 'RSEME_SELECTED_TILE_NOT_FREE_FOR_PET'; + public static RSEME_BOTS_FORBIDDEN_IN_HOTEL: string = 'RSEME_BOTS_FORBIDDEN_IN_HOTEL'; + public static RSEME_BOTS_FORBIDDEN_IN_FLAT: string = 'RSEME_BOTS_FORBIDDEN_IN_FLAT'; + public static RSEME_BOT_LIMIT_REACHED: string = 'RSEME_BOT_LIMIT_REACHED'; + public static RSEME_SELECTED_TILE_NOT_FREE_FOR_BOT: string = 'RSEME_SELECTED_TILE_NOT_FREE_FOR_BOT'; + public static RSEME_BOT_NAME_NOT_ACCEPTED: string = 'RSEME_BOT_NAME_NOT_ACCEPTED'; + + private _message: string; + + constructor(k: string, _arg_2: IRoomSession, _arg_3: string=null) + { + super(k, _arg_2); + + this._message = _arg_3; + } + + public get message(): string + { + return this._message; + } +} \ No newline at end of file diff --git a/src/nitro/session/events/RoomSessionEvent.ts b/src/nitro/session/events/RoomSessionEvent.ts new file mode 100644 index 00000000..ed10277f --- /dev/null +++ b/src/nitro/session/events/RoomSessionEvent.ts @@ -0,0 +1,31 @@ +import { NitroEvent } from '../../../core/events/NitroEvent'; +import { IRoomSession } from '../IRoomSession'; + +export class RoomSessionEvent extends NitroEvent +{ + public static CREATED: string = 'RSE_CREATED'; + public static STARTED: string = 'RSE_STARTED'; + public static ENDED: string = 'RSE_ENDED'; + public static ROOM_DATA: string = 'RSE_ROOM_DATA'; + + private _session: IRoomSession; + private _openLandingView: boolean; + + constructor(type: string, session: IRoomSession, openLandingView: boolean = true) + { + super(type); + + this._session = session; + this._openLandingView = openLandingView; + } + + public get session(): IRoomSession + { + return this._session; + } + + public get openLandingView(): boolean + { + return this._openLandingView; + } +} \ No newline at end of file diff --git a/src/nitro/session/events/RoomSessionFavouriteGroupUpdateEvent.ts b/src/nitro/session/events/RoomSessionFavouriteGroupUpdateEvent.ts new file mode 100644 index 00000000..acdf21cd --- /dev/null +++ b/src/nitro/session/events/RoomSessionFavouriteGroupUpdateEvent.ts @@ -0,0 +1,42 @@ +import { IRoomSession } from '../IRoomSession'; +import { RoomSessionEvent } from './RoomSessionEvent'; + +export class RoomSessionFavouriteGroupUpdateEvent extends RoomSessionEvent +{ + public static RSFGUE_FAVOURITE_GROUP_UPDATE: string = 'RSFGUE_FAVOURITE_GROUP_UPDATE'; + + private _roomIndex: number; + private _habboGroupId: number; + private _habboGroupName: string; + private _status: number; + + constructor(k: IRoomSession, _arg_2: number, _arg_3: number, _arg_4: number, _arg_5: string) + { + super(RoomSessionFavouriteGroupUpdateEvent.RSFGUE_FAVOURITE_GROUP_UPDATE, k); + + this._roomIndex = _arg_2; + this._habboGroupId = _arg_3; + this._habboGroupName = _arg_5; + this._status = _arg_4; + } + + public get _Str_2707(): number + { + return this._roomIndex; + } + + public get _Str_3094(): number + { + return this._habboGroupId; + } + + public get _Str_14525(): string + { + return this._habboGroupName; + } + + public get status(): number + { + return this._status; + } +} \ No newline at end of file diff --git a/src/nitro/session/events/RoomSessionFriendRequestEvent.ts b/src/nitro/session/events/RoomSessionFriendRequestEvent.ts new file mode 100644 index 00000000..557bdb82 --- /dev/null +++ b/src/nitro/session/events/RoomSessionFriendRequestEvent.ts @@ -0,0 +1,35 @@ +import { IRoomSession } from '../IRoomSession'; +import { RoomSessionEvent } from './RoomSessionEvent'; + +export class RoomSessionFriendRequestEvent extends RoomSessionEvent +{ + public static RSFRE_FRIEND_REQUEST: string = 'RSFRE_FRIEND_REQUEST'; + + private _requestId: number = 0; + private _userId: number = 0; + private _userName: string; + + constructor(session: IRoomSession, requestId: number, userId: number, userName: string) + { + super(RoomSessionFriendRequestEvent.RSFRE_FRIEND_REQUEST, session); + + this._requestId = requestId; + this._userId = userId; + this._userName = userName; + } + + public get requestId(): number + { + return this._requestId; + } + + public get userId(): number + { + return this._userId; + } + + public get userName(): string + { + return this._userName; + } +} diff --git a/src/nitro/session/events/RoomSessionNestBreedingSuccessEvent.ts b/src/nitro/session/events/RoomSessionNestBreedingSuccessEvent.ts new file mode 100644 index 00000000..1e4294d1 --- /dev/null +++ b/src/nitro/session/events/RoomSessionNestBreedingSuccessEvent.ts @@ -0,0 +1,28 @@ +import { IRoomSession } from '../IRoomSession'; +import { RoomSessionEvent } from './RoomSessionEvent'; + +export class RoomSessionNestBreedingSuccessEvent extends RoomSessionEvent +{ + public static RSPFUE_NEST_BREEDING_SUCCESS: string = 'RSPFUE_NEST_BREEDING_SUCCESS'; + + private _rarityCategory: number; + private _petId: number; + + constructor(k: IRoomSession, _arg_2: number, _arg_3: number) + { + super(RoomSessionNestBreedingSuccessEvent.RSPFUE_NEST_BREEDING_SUCCESS, k); + + this._petId = _arg_2; + this._rarityCategory = _arg_3; + } + + public get _Str_16731(): number + { + return this._rarityCategory; + } + + public get _Str_2508(): number + { + return this._petId; + } +} \ No newline at end of file diff --git a/src/nitro/session/events/RoomSessionPetBreedingEvent.ts b/src/nitro/session/events/RoomSessionPetBreedingEvent.ts new file mode 100644 index 00000000..63bdb2e2 --- /dev/null +++ b/src/nitro/session/events/RoomSessionPetBreedingEvent.ts @@ -0,0 +1,35 @@ +import { IRoomSession } from '../IRoomSession'; +import { RoomSessionEvent } from './RoomSessionEvent'; + +export class RoomSessionPetBreedingEvent extends RoomSessionEvent +{ + public static RSPFUE_PET_BREEDING: string = 'RSPFUE_PET_BREEDING'; + + private _state: number; + private _ownPetId: number; + private _otherPetId: number; + + constructor(k: IRoomSession, _arg_2: number, _arg_3: number, _arg_4: number) + { + super(RoomSessionPetBreedingEvent.RSPFUE_PET_BREEDING, k); + + this._state = _arg_2; + this._ownPetId = _arg_3; + this._otherPetId = _arg_4; + } + + public get state(): number + { + return this._state; + } + + public get _Str_7440(): number + { + return this._ownPetId; + } + + public get _Str_7663(): number + { + return this._otherPetId; + } +} \ No newline at end of file diff --git a/src/nitro/session/events/RoomSessionPetBreedingResultEvent.ts b/src/nitro/session/events/RoomSessionPetBreedingResultEvent.ts new file mode 100644 index 00000000..bef904fc --- /dev/null +++ b/src/nitro/session/events/RoomSessionPetBreedingResultEvent.ts @@ -0,0 +1,28 @@ +import { IRoomSession } from '../IRoomSession'; +import { RoomSessionEvent } from './RoomSessionEvent'; + +export class RoomSessionPetBreedingResultEvent extends RoomSessionEvent +{ + public static RSPFUE_PET_BREEDING_RESULT: string = 'RSPFUE_PET_BREEDING_RESULT'; + + private _resultData: any; //PetInfoMessageParser + private _otherResultData: any; + + constructor(k: IRoomSession, _arg_2: any, _arg_3: any) + { + super(RoomSessionPetBreedingResultEvent.RSPFUE_PET_BREEDING_RESULT, k); + + this._resultData = _arg_2; + this._otherResultData = _arg_3; + } + + public get _Str_3713(): any + { + return this._resultData; + } + + public get _Str_5840(): any + { + return this._otherResultData; + } +} \ No newline at end of file diff --git a/src/nitro/session/events/RoomSessionPetCommandsUpdateEvent.ts b/src/nitro/session/events/RoomSessionPetCommandsUpdateEvent.ts new file mode 100644 index 00000000..2183a330 --- /dev/null +++ b/src/nitro/session/events/RoomSessionPetCommandsUpdateEvent.ts @@ -0,0 +1,35 @@ +import { IRoomSession } from '../IRoomSession'; +import { RoomSessionEvent } from './RoomSessionEvent'; + +export class RoomSessionPetCommandsUpdateEvent extends RoomSessionEvent +{ + public static PET_COMMANDS: string = 'RSPIUE_ENABLED_PET_COMMANDS'; + + private _petId: number; + private _allCommandIds: number[]; + private _enabledCommandIds: number[]; + + constructor(k: IRoomSession, id: number, commands: number[], enabledCommands: number[]) + { + super(RoomSessionPetCommandsUpdateEvent.PET_COMMANDS, k); + + this._petId = id; + this._allCommandIds = commands; + this._enabledCommandIds = enabledCommands; + } + + public get id(): number + { + return this._petId; + } + + public get commands(): number[] + { + return this._allCommandIds; + } + + public get enabledCommands(): number[] + { + return this._enabledCommandIds; + } +} \ No newline at end of file diff --git a/src/nitro/session/events/RoomSessionPetFigureUpdateEvent.ts b/src/nitro/session/events/RoomSessionPetFigureUpdateEvent.ts new file mode 100644 index 00000000..a1eda948 --- /dev/null +++ b/src/nitro/session/events/RoomSessionPetFigureUpdateEvent.ts @@ -0,0 +1,28 @@ +import { IRoomSession } from '../IRoomSession'; +import { RoomSessionEvent } from './RoomSessionEvent'; + +export class RoomSessionPetFigureUpdateEvent extends RoomSessionEvent +{ + public static PET_FIGURE_UPDATE: string = 'RSPFUE_PET_FIGURE_UPDATE'; + + private _petId: number; + private _figure: string; + + constructor(k: IRoomSession, id: number, figure: string) + { + super(RoomSessionPetFigureUpdateEvent.PET_FIGURE_UPDATE, k); + + this._petId = id; + this._figure = figure; + } + + public get id(): number + { + return this._petId; + } + + public get figure(): string + { + return this._figure; + } +} \ No newline at end of file diff --git a/src/nitro/session/events/RoomSessionPetInfoUpdateEvent.ts b/src/nitro/session/events/RoomSessionPetInfoUpdateEvent.ts new file mode 100644 index 00000000..a40f31b3 --- /dev/null +++ b/src/nitro/session/events/RoomSessionPetInfoUpdateEvent.ts @@ -0,0 +1,22 @@ +import { IRoomSession } from '../IRoomSession'; +import { RoomPetData } from '../RoomPetData'; +import { RoomSessionEvent } from './RoomSessionEvent'; + +export class RoomSessionPetInfoUpdateEvent extends RoomSessionEvent +{ + public static PET_INFO: string = 'RSPIUE_PET_INFO'; + + private _petInfo: RoomPetData; + + constructor(k: IRoomSession, _arg_2: RoomPetData) + { + super(RoomSessionPetInfoUpdateEvent.PET_INFO, k); + + this._petInfo = _arg_2; + } + + public get _Str_24727():RoomPetData + { + return this._petInfo; + } +} \ No newline at end of file diff --git a/src/nitro/session/events/RoomSessionPetLevelUpdateEvent.ts b/src/nitro/session/events/RoomSessionPetLevelUpdateEvent.ts new file mode 100644 index 00000000..46c2b62a --- /dev/null +++ b/src/nitro/session/events/RoomSessionPetLevelUpdateEvent.ts @@ -0,0 +1,28 @@ +import { IRoomSession } from '../IRoomSession'; +import { RoomSessionEvent } from './RoomSessionEvent'; + +export class RoomSessionPetLevelUpdateEvent extends RoomSessionEvent +{ + public static RSPLUE_PET_LEVEL_UPDATE: string = 'RSPLUE_PET_LEVEL_UPDATE'; + + private _petId: number; + private _level: number; + + constructor(k: IRoomSession, _arg_2: number, _arg_3: number) + { + super(RoomSessionPetLevelUpdateEvent.RSPLUE_PET_LEVEL_UPDATE, k); + + this._petId = _arg_2; + this._level = _arg_3; + } + + public get _Str_2508(): number + { + return this._petId; + } + + public get level(): number + { + return this._level; + } +} \ No newline at end of file diff --git a/src/nitro/session/events/RoomSessionPetPackageEvent.ts b/src/nitro/session/events/RoomSessionPetPackageEvent.ts new file mode 100644 index 00000000..e311c08c --- /dev/null +++ b/src/nitro/session/events/RoomSessionPetPackageEvent.ts @@ -0,0 +1,43 @@ +import { PetFigureData } from '../../communication/messages/parser/inventory/pets/PetFigureData'; +import { IRoomSession } from '../IRoomSession'; +import { RoomSessionEvent } from './RoomSessionEvent'; + +export class RoomSessionPetPackageEvent extends RoomSessionEvent +{ + public static RSOPPE_OPEN_PET_PACKAGE_REQUESTED: string = 'RSOPPE_OPEN_PET_PACKAGE_REQUESTED'; + public static RSOPPE_OPEN_PET_PACKAGE_RESULT: string = 'RSOPPE_OPEN_PET_PACKAGE_RESULT'; + + private _objectId: number = -1; + private _figureData:PetFigureData; + private _nameValidationStatus: number = 0; + private _nameValidationInfo: string = null; + + constructor(k: string, _arg_2: IRoomSession, _arg_3: number, _arg_4: PetFigureData, _arg_5: number, _arg_6: string) + { + super(k, _arg_2); + this._objectId = _arg_3; + this._figureData = _arg_4; + this._nameValidationStatus = _arg_5; + this._nameValidationInfo = _arg_6; + } + + public get _Str_1577(): number + { + return this._objectId; + } + + public get figureData():PetFigureData + { + return this._figureData; + } + + public get nameValidationStatus(): number + { + return this._nameValidationStatus; + } + + public get nameValidationInfo(): string + { + return this._nameValidationInfo; + } +} \ No newline at end of file diff --git a/src/nitro/session/events/RoomSessionPetStatusUpdateEvent.ts b/src/nitro/session/events/RoomSessionPetStatusUpdateEvent.ts new file mode 100644 index 00000000..444f79aa --- /dev/null +++ b/src/nitro/session/events/RoomSessionPetStatusUpdateEvent.ts @@ -0,0 +1,49 @@ +import { IRoomSession } from '../IRoomSession'; +import { RoomSessionEvent } from './RoomSessionEvent'; + +export class RoomSessionPetStatusUpdateEvent extends RoomSessionEvent +{ + public static RSPFUE_PET_STATUS_UPDATE: string = 'RSPFUE_PET_STATUS_UPDATE'; + + private _petId: number; + private _canBreed: boolean; + private _canHarvest: boolean; + private _canRevive: boolean; + private _hasBreedingPermission: boolean; + + constructor(k: IRoomSession, _arg_2: number, _arg_3: boolean, _arg_4: boolean, _arg_5: boolean, _arg_6: boolean) + { + super(RoomSessionPetStatusUpdateEvent.RSPFUE_PET_STATUS_UPDATE, k); + + this._petId = _arg_2; + this._canBreed = _arg_3; + this._canHarvest = _arg_4; + this._canRevive = _arg_5; + this._hasBreedingPermission = _arg_6; + } + + public get _Str_2508(): number + { + return this._petId; + } + + public get _Str_2934(): boolean + { + return this._canBreed; + } + + public get _Str_3068(): boolean + { + return this._canHarvest; + } + + public get _Str_2898(): boolean + { + return this._canRevive; + } + + public get _Str_2921(): boolean + { + return this._hasBreedingPermission; + } +} \ No newline at end of file diff --git a/src/nitro/session/events/RoomSessionPollEvent.ts b/src/nitro/session/events/RoomSessionPollEvent.ts new file mode 100644 index 00000000..87ea2e98 --- /dev/null +++ b/src/nitro/session/events/RoomSessionPollEvent.ts @@ -0,0 +1,49 @@ +import { IRoomSession } from '../IRoomSession'; +import { RoomSessionEvent } from './RoomSessionEvent'; + +export class RoomSessionPollEvent extends RoomSessionEvent +{ + public static VOTE_QUESTION: string = 'RSPE_VOTE_QUESTION'; + public static VOTE_RESULT: string = 'RSPE_VOTE_RESULT'; + + private _question: string = ''; + private _choices: string[]; + private _SafeStr_7651: string[]; + private _SafeStr_7654: number = 0; + + constructor(_arg_1: string, _arg_2: IRoomSession, _arg_3: string, _arg_4: string[], _arg_5: string[]=null, _arg_6: number=0) + { + super(_arg_1, _arg_2); + + this._choices = []; + this._SafeStr_7651 = []; + this._question = _arg_3; + this._choices = _arg_4; + this._SafeStr_7651 = _arg_5; + if(this._SafeStr_7651 == null) + { + this._SafeStr_7651 = []; + } + this._SafeStr_7654 = _arg_6; + } + + public get question(): string + { + return this._question; + } + + public get choices(): string[] + { + return this._choices.slice(); + } + + public get _SafeStr_4173(): string[] + { + return this._SafeStr_7651.slice(); + } + + public get _SafeStr_4174(): number + { + return this._SafeStr_7654; + } +} \ No newline at end of file diff --git a/src/nitro/session/events/RoomSessionPresentEvent.ts b/src/nitro/session/events/RoomSessionPresentEvent.ts new file mode 100644 index 00000000..b0f52a5d --- /dev/null +++ b/src/nitro/session/events/RoomSessionPresentEvent.ts @@ -0,0 +1,64 @@ +import { IRoomSession } from '../IRoomSession'; +import { RoomSessionEvent } from './RoomSessionEvent'; + +export class RoomSessionPresentEvent extends RoomSessionEvent +{ + public static RSPE_PRESENT_OPENED: string = 'RSPE_PRESENT_OPENED'; + + private _classId: number = 0; + private _itemType: string = ''; + private _productCode: string; + private _placedItemId: number = 0; + private _placedItemType: string = ''; + private _placedInRoom: boolean; + private _petFigureString: string; + + constructor(k: string, _arg_2: IRoomSession, classId: number, itemType: string, productCode: string, placedItemId: number, placedItemType: string, placedInRoom: boolean, petFigureString: string) + { + super(k, _arg_2); + + this._classId = classId; + this._itemType = itemType; + this._productCode = productCode; + this._placedItemId = placedItemId; + this._placedItemType = placedItemType; + this._placedInRoom = placedInRoom; + this._petFigureString = petFigureString; + } + + public get classId(): number + { + return this._classId; + } + + + public get itemType(): string + { + return this._itemType; + } + + public get productCode(): string + { + return this._productCode; + } + + public get placedItemId(): number + { + return this._placedItemId; + } + + public get placedInRoom(): boolean + { + return this._placedInRoom; + } + + public get placedItemType(): string + { + return this._placedItemType; + } + + public get petFigureString(): string + { + return this._petFigureString; + } +} diff --git a/src/nitro/session/events/RoomSessionPropertyUpdateEvent.ts b/src/nitro/session/events/RoomSessionPropertyUpdateEvent.ts new file mode 100644 index 00000000..6b076786 --- /dev/null +++ b/src/nitro/session/events/RoomSessionPropertyUpdateEvent.ts @@ -0,0 +1,12 @@ +import { IRoomSession } from '../IRoomSession'; +import { RoomSessionEvent } from './RoomSessionEvent'; + +export class RoomSessionPropertyUpdateEvent extends RoomSessionEvent +{ + public static RSDUE_ALLOW_PETS: string = 'RSDUE_ALLOW_PETS'; + + constructor(k: string, _arg_2: IRoomSession) + { + super(k, _arg_2); + } +} \ No newline at end of file diff --git a/src/nitro/session/events/RoomSessionQueueEvent.ts b/src/nitro/session/events/RoomSessionQueueEvent.ts new file mode 100644 index 00000000..18089e5b --- /dev/null +++ b/src/nitro/session/events/RoomSessionQueueEvent.ts @@ -0,0 +1,57 @@ +import { IRoomSession } from '../IRoomSession'; +import { RoomSessionEvent } from './RoomSessionEvent'; + +export class RoomSessionQueueEvent extends RoomSessionEvent +{ + public static RSQE_QUEUE_STATUS: string = 'RSQE_QUEUE_STATUS'; + public static C: string = 'c'; + public static D: string = 'd'; + public static _Str_14665: number = 2; + public static _Str_14078: number = 1; + + private _name: string; + private _target: number; + private _queues: Map; + private _isActive: boolean; + private _activeQueue: string; + + constructor(k: IRoomSession, _arg_2: string, _arg_3: number, _arg_4: boolean = false) + { + super(RoomSessionQueueEvent.RSQE_QUEUE_STATUS, k); + + this._name = _arg_2; + this._target = _arg_3; + this._queues = new Map(); + this._isActive = _arg_4; + } + + public get isActive(): boolean + { + return this._isActive; + } + + public get _Str_26076(): string + { + return this._name; + } + + public get _Str_22709(): number + { + return this._target; + } + + public get _Str_14282(): string[] + { + return Array.from(this._queues.keys()); + } + + public _Str_11510(k: string): number + { + return this._queues.get(k); + } + + public _Str_17628(k: string, _arg_2: number): void + { + this._queues.set(k, _arg_2); + } +} \ No newline at end of file diff --git a/src/nitro/session/events/RoomSessionUserBadgesEvent.ts b/src/nitro/session/events/RoomSessionUserBadgesEvent.ts new file mode 100644 index 00000000..00b33b9d --- /dev/null +++ b/src/nitro/session/events/RoomSessionUserBadgesEvent.ts @@ -0,0 +1,29 @@ +import { IRoomSession } from '../IRoomSession'; +import { RoomSessionEvent } from './RoomSessionEvent'; + +export class RoomSessionUserBadgesEvent extends RoomSessionEvent +{ + public static RSUBE_BADGES: string = 'RSUBE_BADGES'; + + private _userId: number = 0; + private _badges: string[]; + + constructor(k: IRoomSession, _arg_2: number, _arg_3: string[]) + { + super(RoomSessionUserBadgesEvent.RSUBE_BADGES, k); + + this._badges = []; + this._userId = _arg_2; + this._badges = _arg_3; + } + + public get userId(): number + { + return this._userId; + } + + public get badges(): string[] + { + return this._badges; + } +} \ No newline at end of file diff --git a/src/nitro/session/events/RoomSessionUserDataUpdateEvent.ts b/src/nitro/session/events/RoomSessionUserDataUpdateEvent.ts new file mode 100644 index 00000000..ed7969fb --- /dev/null +++ b/src/nitro/session/events/RoomSessionUserDataUpdateEvent.ts @@ -0,0 +1,22 @@ +import { IRoomSession } from '../IRoomSession'; +import { RoomUserData } from '../RoomUserData'; +import { RoomSessionEvent } from './RoomSessionEvent'; + +export class RoomSessionUserDataUpdateEvent extends RoomSessionEvent +{ + public static USER_DATA_UPDATED: string = 'RMUDUE_USER_DATA_UPDATED'; + + private _addedUsers: RoomUserData[]; + + constructor(session: IRoomSession, addedUsers: RoomUserData[]) + { + super(RoomSessionUserDataUpdateEvent.USER_DATA_UPDATED, session); + + this._addedUsers = addedUsers; + } + + public get addedUsers(): RoomUserData[] + { + return this._addedUsers; + } +} \ No newline at end of file diff --git a/src/nitro/session/events/RoomSessionUserFigureUpdateEvent.ts b/src/nitro/session/events/RoomSessionUserFigureUpdateEvent.ts new file mode 100644 index 00000000..15bf7b23 --- /dev/null +++ b/src/nitro/session/events/RoomSessionUserFigureUpdateEvent.ts @@ -0,0 +1,48 @@ +import { IRoomSession } from '../IRoomSession'; +import { RoomSessionEvent } from './RoomSessionEvent'; + +export class RoomSessionUserFigureUpdateEvent extends RoomSessionEvent +{ + public static RSUBE_FIGURE: string = 'RSUBE_FIGURE'; + + private _userId: number = 0; + private _figure: string = ''; + private _gender: string = ''; + private _customInfo: string = ''; + private _achievementScore: number; + + constructor(k: IRoomSession, _arg_2: number, _arg_3: string, _arg_4: string, _arg_5: string, _arg_6: number) + { + super(RoomSessionUserFigureUpdateEvent.RSUBE_FIGURE, k); + this._userId = _arg_2; + this._figure = _arg_3; + this._gender = _arg_4; + this._customInfo = _arg_5; + this._achievementScore = _arg_6; + } + + public get userId(): number + { + return this._userId; + } + + public get figure(): string + { + return this._figure; + } + + public get gender(): string + { + return this._gender; + } + + public get _Str_9690(): string + { + return this._customInfo; + } + + public get activityPoints(): number + { + return this._achievementScore; + } +} \ No newline at end of file diff --git a/src/nitro/session/events/RoomSessionUserTagsEvent.ts b/src/nitro/session/events/RoomSessionUserTagsEvent.ts new file mode 100644 index 00000000..7d2f6489 --- /dev/null +++ b/src/nitro/session/events/RoomSessionUserTagsEvent.ts @@ -0,0 +1,27 @@ +import { NitroEvent } from '../../../core/events/NitroEvent'; + +export class RoomSessionUserTagsEvent extends NitroEvent +{ + public static UTRE_USER_TAGS_RECEIVED: string = 'UTRE_USER_TAGS_RECEIVED'; + + private _userId: number; + private _tags: string[]; + + constructor(k: number, _arg_2: string[]) + { + super(RoomSessionUserTagsEvent.UTRE_USER_TAGS_RECEIVED); + + this._userId = k; + this._tags = _arg_2; + } + + public get userId(): number + { + return this._userId; + } + + public get tags(): string[] + { + return this._tags; + } +} \ No newline at end of file diff --git a/src/nitro/session/events/RoomSessionWordQuizEvent.ts b/src/nitro/session/events/RoomSessionWordQuizEvent.ts new file mode 100644 index 00000000..268a5b62 --- /dev/null +++ b/src/nitro/session/events/RoomSessionWordQuizEvent.ts @@ -0,0 +1,111 @@ +import { IRoomSession } from '../IRoomSession'; +import { RoomSessionEvent } from './RoomSessionEvent'; + +export class RoomSessionWordQuizEvent extends RoomSessionEvent +{ + public static RWPUW_NEW_QUESTION: string = 'RWPUW_NEW_QUESTION'; + public static RWPUW_QUESION_FINSIHED: string = 'RWPUW_QUESION_FINSIHED'; + public static RWPUW_QUESTION_ANSWERED: string = 'RWPUW_QUESTION_ANSWERED'; + + private _id: number = -1; + private _pollType: string = null; + private _pollId: number = -1; + private _questionId: number = -1; + private _duration: number = -1; + private _question: string[] = null; + private _userId: number = -1; + private _value: string; + private _answerCounts: Map; + + constructor(k: string, _arg_2: IRoomSession, _arg_3: number = -1) + { + super(k, _arg_2); + + this._id = _arg_3; + } + + public get id(): number + { + return this._id; + } + + public get _Str_5302(): string + { + return this._pollType; + } + + public set _Str_5302(k: string) + { + this._pollType = k; + } + + public get _Str_5213(): number + { + return this._pollId; + } + + public set _Str_5213(k: number) + { + this._pollId = k; + } + + public get _Str_3218(): number + { + return this._questionId; + } + + public set _Str_3218(k: number) + { + this._questionId = k; + } + + public get duration(): number + { + return this._duration; + } + + public set duration(k: number) + { + this._duration = k; + } + + public get question(): string[] + { + return this._question; + } + + public set question(k: string[]) + { + this._question = k; + } + + public get userId(): number + { + return this._userId; + } + + public set userId(k: number) + { + this._userId = k; + } + + public get value(): string + { + return this._value; + } + + public set value(k: string) + { + this._value = k; + } + + public get _Str_4036(): Map + { + return this._answerCounts; + } + + public set _Str_4036(k: Map) + { + this._answerCounts = k; + } +} \ No newline at end of file diff --git a/src/nitro/session/events/SessionDataPreferencesEvent.ts b/src/nitro/session/events/SessionDataPreferencesEvent.ts new file mode 100644 index 00000000..7fa94849 --- /dev/null +++ b/src/nitro/session/events/SessionDataPreferencesEvent.ts @@ -0,0 +1,20 @@ +import { NitroEvent } from '../../../core/events/NitroEvent'; + +export class SessionDataPreferencesEvent extends NitroEvent +{ + public static APUE_UPDATED: string = 'APUE_UPDATED'; + + private _uiFlags: number; + + constructor(k: number) + { + super(SessionDataPreferencesEvent.APUE_UPDATED); + + this._uiFlags = k; + } + + public get _Str_8444(): number + { + return this._uiFlags; + } +} \ No newline at end of file diff --git a/src/nitro/session/events/UserNameUpdateEvent.ts b/src/nitro/session/events/UserNameUpdateEvent.ts new file mode 100644 index 00000000..0560966b --- /dev/null +++ b/src/nitro/session/events/UserNameUpdateEvent.ts @@ -0,0 +1,20 @@ +import { NitroEvent } from '../../../core/events/NitroEvent'; + +export class UserNameUpdateEvent extends NitroEvent +{ + public static UNUE_NAME_UPDATED: string = 'unue_name_updated'; + + private _name: string; + + constructor(k: string) + { + super(UserNameUpdateEvent.UNUE_NAME_UPDATED); + + this._name = k; + } + + public get name(): string + { + return this._name; + } +} \ No newline at end of file diff --git a/src/nitro/session/events/_Str_3051.ts b/src/nitro/session/events/_Str_3051.ts new file mode 100644 index 00000000..673870b8 --- /dev/null +++ b/src/nitro/session/events/_Str_3051.ts @@ -0,0 +1,100 @@ +import { IRoomSession } from '../IRoomSession'; +import { RoomSessionEvent } from './RoomSessionEvent'; + +export class _Str_3051 extends RoomSessionEvent +{ + public static RSPE_POLL_OFFER: string = 'RSPE_POLL_OFFER'; + public static ERROR: string = 'RSPE_POLL_ERROR'; + public static RSPE_POLL_CONTENT: string = 'RSPE_POLL_CONTENT'; + + private _id: number = -1; + private _headline: string; + private _summary: string; + private _Str_5366: number = 0; + private _Str_5879: string = ''; + private _Str_4781: string = ''; + private _Str_5432: string[] = null; + private _Str_4353: boolean = false; + + constructor(k: string, _arg_2: IRoomSession, _arg_3: number) + { + super(k, _arg_2); + + this._id = _arg_3; + } + + public get id(): number + { + return this._id; + } + + public get headline(): string + { + return this._headline; + } + + public set headline(k: string) + { + this._headline = k; + } + + public get summary(): string + { + return this._summary; + } + + public set summary(k: string) + { + this._summary = k; + } + + public get _Str_6760(): number + { + return this._Str_5366; + } + + public set _Str_6760(k: number) + { + this._Str_5366 = k; + } + + public get _Str_6013(): string + { + return this._Str_5879; + } + + public set _Str_6013(k: string) + { + this._Str_5879 = k; + } + + public get _Str_5838(): string + { + return this._Str_4781; + } + + public set _Str_5838(k: string) + { + this._Str_4781 = k; + } + + public get _Str_5643(): string[] + { + return this._Str_5432; + } + + public set _Str_5643(k: string[]) + { + this._Str_5432 = k; + } + + public get _Str_6196(): boolean + { + return this._Str_4353; + } + + public set _Str_6196(k: boolean) + { + this._Str_4353 = k; + } +} \ No newline at end of file diff --git a/src/nitro/session/furniture/FurnitureData.ts b/src/nitro/session/furniture/FurnitureData.ts new file mode 100644 index 00000000..5207d39e --- /dev/null +++ b/src/nitro/session/furniture/FurnitureData.ts @@ -0,0 +1,222 @@ +import { IFurnitureData } from './IFurnitureData'; + +export class FurnitureData implements IFurnitureData +{ + private _type: string; + private _id: number; + private _className: string; + private _fullName: string; + private _category: string; + private _hasIndexedColor: boolean; + private _colourIndex: number; + private _revision: number; + private _tileSizeX: number; + private _tileSizeY: number; + private _tileSizeZ: number; + private _colors: number[]; + private _localizedName: string; + private _description: string; + private _adUrl: string; + private _purchaseOfferId: number; + private _rentOfferId: number; + private _customParams: string; + private _specialType: number; + private _purchaseCouldBeUsedForBuyout: boolean; + private _rentCouldBeUsedForBuyout: boolean; + private _availableForBuildersClub: boolean; + private _canStandOn: boolean; + private _canSitOn: boolean; + private _canLayOn: boolean; + private _excludedFromDynamic: boolean; + private _furniLine: string; + private _environment: string; + private _rare: boolean; + + constructor(type: string, id: number, fullName: string, className: string, category: string, localizedName: string, description: string, revision: number, tileSizeX: number, tileSizeY: number, tileSizeZ: number, colors: number[], hadIndexedColor: boolean, colorIndex: number, adUrl: string, purchaseOfferId: number, purchaseCouldBeUsedForBuyout: boolean, rentOfferId: number, rentCouldBeUsedForBuyout: boolean, availableForBuildersClub: boolean, customParams: string, specialType: number, canStandOn: boolean, canSitOn: boolean, canLayOn: boolean, excludedfromDynamic: boolean, furniLine: string, environment: string, rare: boolean) + { + this._type = type; + this._id = id; + this._fullName = fullName; + this._className = className; + this._category = category; + this._revision = revision; + this._tileSizeX = tileSizeX; + this._tileSizeY = tileSizeY; + this._tileSizeZ = tileSizeZ; + this._colors = colors; + this._hasIndexedColor = hadIndexedColor; + this._colourIndex = colorIndex; + this._localizedName = localizedName; + this._description = description; + this._adUrl = adUrl; + this._purchaseOfferId = purchaseOfferId; + this._purchaseCouldBeUsedForBuyout = purchaseCouldBeUsedForBuyout; + this._rentOfferId = rentOfferId; + this._rentCouldBeUsedForBuyout = rentCouldBeUsedForBuyout; + this._customParams = customParams; + this._specialType = specialType; + this._availableForBuildersClub = availableForBuildersClub; + this._canStandOn = canStandOn; + this._canSitOn = canSitOn; + this._canLayOn = canLayOn; + this._excludedFromDynamic = excludedfromDynamic; + this._furniLine = furniLine; + this._environment = environment; + this._rare = rare; + } + + public get type(): string + { + return this._type; + } + + public get id(): number + { + return this._id; + } + + public get className(): string + { + return this._className; + } + + public set className(k: string) + { + this._className = k; + } + + public get fullName(): string + { + return this._fullName; + } + + public get category(): string + { + return this._category; + } + + public get hasIndexedColor(): boolean + { + return this._hasIndexedColor; + } + + public get colorIndex(): number + { + return this._colourIndex; + } + + public get revision(): number + { + return this._revision; + } + + public get tileSizeX(): number + { + return this._tileSizeX; + } + + public get tileSizeY(): number + { + return this._tileSizeY; + } + + public get tileSizeZ(): number + { + return this._tileSizeZ; + } + + public get colors(): number[] + { + return this._colors; + } + + public get name(): string + { + return this._localizedName; + } + + public get description(): string + { + return this._description; + } + + public get adUrl(): string + { + return this._adUrl; + } + + public get purchaseOfferId(): number + { + return this._purchaseOfferId; + } + + public get customParams(): string + { + return this._customParams; + } + + public get specialType(): number + { + return this._specialType; + } + + public get rentOfferId(): number + { + return this._rentOfferId; + } + + public get purchaseCouldBeUsedForBuyout(): boolean + { + return this._purchaseCouldBeUsedForBuyout; + } + + public get rentCouldBeUsedForBuyout(): boolean + { + return this._rentCouldBeUsedForBuyout; + } + + public get availableForBuildersClub(): boolean + { + return this._availableForBuildersClub; + } + + public get canStandOn(): boolean + { + return this._canStandOn; + } + + public get canSitOn(): boolean + { + return this._canSitOn; + } + + public get canLayOn(): boolean + { + return this._canLayOn; + } + + public get isExternalImage(): boolean + { + return !(this._className.indexOf('external_image') === -1); + } + + public get excludeDynamic(): boolean + { + return this._excludedFromDynamic; + } + + public get furniLine(): string + { + return this._furniLine; + } + + public get environment(): string + { + return this._environment; + } + + public get rare(): boolean + { + return this._rare; + } +} diff --git a/src/nitro/session/furniture/FurnitureDataParser.ts b/src/nitro/session/furniture/FurnitureDataParser.ts new file mode 100644 index 00000000..68ba61c9 --- /dev/null +++ b/src/nitro/session/furniture/FurnitureDataParser.ts @@ -0,0 +1,136 @@ +import { EventDispatcher } from '../../../core/events/EventDispatcher'; +import { NitroEvent } from '../../../core/events/NitroEvent'; +import { INitroLocalizationManager } from '../../localization/INitroLocalizationManager'; +import { FurnitureData } from './FurnitureData'; +import { FurnitureType } from './FurnitureType'; +import { IFurnitureData } from './IFurnitureData'; +import { NitroLogger } from '../../../core/common/logger/NitroLogger'; + +export class FurnitureDataParser extends EventDispatcher +{ + public static FURNITURE_DATA_READY: string = 'FDP_FURNITURE_DATA_READY'; + public static FURNITURE_DATA_ERROR: string = 'FDP_FURNITURE_DATA_ERROR'; + + private _floorItems: Map; + private _wallItems: Map; + private _localization: INitroLocalizationManager; + private _nitroLogger: NitroLogger; + + + constructor(floorItems: Map, wallItems: Map, localization: INitroLocalizationManager) + { + super(); + + this._floorItems = floorItems; + this._wallItems = wallItems; + this._localization = localization; + this._nitroLogger = new NitroLogger(this.constructor.name); + } + + public loadFurnitureData(url: string): void + { + if(!url) return; + + fetch(url) + .then(response => response.json()) + .then(data => this.onFurnitureDataLoaded(data)) + .catch(err => this.onFurnitureDataError(err)); + } + + private onFurnitureDataLoaded(data: { [index: string]: any }): void + { + if(!data) return; + + if((typeof data.roomitemtypes == 'undefined') || (typeof data.wallitemtypes == 'undefined')) this._nitroLogger.warn('Could not find `roomitemtypes` or `wallitemtypes` in furnidata.'); + + if(data.roomitemtypes) this.parseFloorItems(data.roomitemtypes); + + if(data.wallitemtypes) this.parseWallItems(data.wallitemtypes); + + this.dispatchEvent(new NitroEvent(FurnitureDataParser.FURNITURE_DATA_READY)); + } + + private onFurnitureDataError(error: Error): void + { + if(!error) return; + + console.error(error); + + this.dispatchEvent(new NitroEvent(FurnitureDataParser.FURNITURE_DATA_ERROR)); + } + + private parseFloorItems(data: any): void + { + if(!data || !data.furnitype) return; + + for(const furniture of data.furnitype) + { + if(!furniture) continue; + + const colors: number[] = []; + + if(furniture.partcolors) + { + for(const color of furniture.partcolors.color) + { + let colorCode = (color as string); + + if(colorCode.charAt(0) === '#') + { + colorCode = colorCode.replace('#', ''); + + colors.push(parseInt(colorCode, 16)); + } + else + { + colors.push((parseInt(colorCode, 16))); + } + } + } + + const classSplit = (furniture.classname as string).split('*'); + const className = classSplit[0]; + const colorIndex = ((classSplit.length > 1) ? parseInt(classSplit[1]) : 0); + const hasColorIndex = (classSplit.length > 1); + + const furnitureData = new FurnitureData(FurnitureType.FLOOR, furniture.id, furniture.classname, className, furniture.category, furniture.name, furniture.description, furniture.revision, furniture.xdim, furniture.ydim, 0, colors, hasColorIndex, colorIndex, furniture.adurl, furniture.offerid, furniture.buyout, furniture.rentofferid, furniture.rentbuyout, furniture.bc, furniture.customparams, furniture.specialtype, furniture.canstandon, furniture.cansiton, furniture.canlayon, furniture.excludeddynamic, furniture.furniline, furniture.environment, furniture.rare); + + this._floorItems.set(furnitureData.id, furnitureData); + + this.updateLocalizations(furnitureData); + } + } + + private parseWallItems(data: any): void + { + if(!data || !data.furnitype) return; + + for(const furniture of data.furnitype) + { + if(!furniture) continue; + + const furnitureData = new FurnitureData(FurnitureType.WALL, furniture.id, furniture.classname, furniture.classname, furniture.category, furniture.name, furniture.description, furniture.revision, 0, 0, 0, null, false, 0, furniture.adurl, furniture.offerid, furniture.buyout, furniture.rentofferid, furniture.rentbuyout, furniture.bc, null, furniture.specialtype, false, false, false, furniture.excludeddynamic, furniture.furniline, furniture.environment, furniture.rare); + + this._wallItems.set(furnitureData.id, furnitureData); + + this.updateLocalizations(furnitureData); + } + } + + private updateLocalizations(furniture: FurnitureData): void + { + if(!this._localization) return; + + switch(furniture.type) + { + case FurnitureType.FLOOR: + this._localization.setValue(('roomItem.name.' + furniture.id), furniture.name); + this._localization.setValue(('roomItem.desc.' + furniture.id), furniture.description); + return; + case FurnitureType.WALL: + this._localization.setValue(('wallItem.name.' + furniture.id), furniture.name); + this._localization.setValue(('wallItem.desc.' + furniture.id), furniture.description); + return; + } + } +} diff --git a/src/nitro/session/furniture/FurnitureType.ts b/src/nitro/session/furniture/FurnitureType.ts new file mode 100644 index 00000000..a63ca207 --- /dev/null +++ b/src/nitro/session/furniture/FurnitureType.ts @@ -0,0 +1,10 @@ +export enum FurnitureType +{ + FLOOR = 'S', + WALL = 'I', + EFFECT = 'E', + BADGE = 'B', + ROBOT = 'R', + HABBO_CLUB = 'H', + PET = 'P' +} \ No newline at end of file diff --git a/src/nitro/session/furniture/IFurnitureData.ts b/src/nitro/session/furniture/IFurnitureData.ts new file mode 100644 index 00000000..0ebc9c78 --- /dev/null +++ b/src/nitro/session/furniture/IFurnitureData.ts @@ -0,0 +1,33 @@ +export interface IFurnitureData +{ + type: string; + id: number; + className: string; + fullName: string; + category: string; + hasIndexedColor: boolean; + colorIndex: number; + revision: number; + tileSizeX: number; + tileSizeY: number; + tileSizeZ: number; + colors: number[]; + name: string; + description: string; + adUrl: string; + purchaseOfferId: number; + rentOfferId: number; + customParams: string; + specialType: number; + purchaseCouldBeUsedForBuyout: boolean; + rentCouldBeUsedForBuyout: boolean; + availableForBuildersClub: boolean; + canStandOn: boolean; + canSitOn: boolean; + canLayOn: boolean; + isExternalImage: boolean; + excludeDynamic: boolean; + furniLine: string; + environment: string; + rare: boolean; +} diff --git a/src/nitro/session/furniture/IFurnitureDataListener.ts b/src/nitro/session/furniture/IFurnitureDataListener.ts new file mode 100644 index 00000000..e94ec16f --- /dev/null +++ b/src/nitro/session/furniture/IFurnitureDataListener.ts @@ -0,0 +1,4 @@ +export interface IFurnitureDataListener +{ + loadFurnitureData(): void; +} \ No newline at end of file diff --git a/src/nitro/session/handler/BaseHandler.ts b/src/nitro/session/handler/BaseHandler.ts new file mode 100644 index 00000000..642aa624 --- /dev/null +++ b/src/nitro/session/handler/BaseHandler.ts @@ -0,0 +1,45 @@ +import { Disposable } from '../../../core/common/disposable/Disposable'; +import { IConnection } from '../../../core/communication/connections/IConnection'; +import { IRoomHandlerListener } from '../IRoomHandlerListener'; + +export class BaseHandler extends Disposable +{ + private _connection: IConnection; + private _listener: IRoomHandlerListener; + private _roomId: number; + + constructor(connection: IConnection, listener: IRoomHandlerListener) + { + super(); + + this._connection = connection; + this._listener = listener; + this._roomId = 0; + } + + protected onDispose(): void + { + this._connection = null; + this._listener = null; + } + + public setRoomId(id: number): void + { + this._roomId = id; + } + + public get connection(): IConnection + { + return this._connection; + } + + public get listener(): IRoomHandlerListener + { + return this._listener; + } + + public get roomId(): number + { + return this._roomId; + } +} \ No newline at end of file diff --git a/src/nitro/session/handler/GenericErrorHandler.ts b/src/nitro/session/handler/GenericErrorHandler.ts new file mode 100644 index 00000000..004e4cfd --- /dev/null +++ b/src/nitro/session/handler/GenericErrorHandler.ts @@ -0,0 +1,44 @@ +import { IConnection } from '../../../core/communication/connections/IConnection'; +import { GenericErrorEvent } from '../../communication/messages/incoming/generic/GenericErrorEvent'; +import { GenericErrorEnum } from '../enum/GenericErrorEnum'; +import { RoomSessionErrorMessageEvent } from '../events/RoomSessionErrorMessageEvent'; +import { IRoomHandlerListener } from '../IRoomHandlerListener'; +import { BaseHandler } from './BaseHandler'; + +export class GenericErrorHandler extends BaseHandler +{ + constructor(connection: IConnection, listener: IRoomHandlerListener) + { + super(connection, listener); + + connection.addMessageEvent(new GenericErrorEvent(this.onRoomGenericError.bind(this))); + } + + private onRoomGenericError(event: GenericErrorEvent): void + { + if(!(event instanceof GenericErrorEvent)) return; + + const parser = event.getParser(); + + if(!parser) return; + + const roomSession = this.listener.getSession(this.roomId); + + if(!roomSession) return; + + let type: string = null; + + switch(parser.errorCode) + { + case GenericErrorEnum.KICKED_OUT_OF_ROOM: + type = RoomSessionErrorMessageEvent.RSEME_KICKED; + break; + default: + return; + } + + if(!type || type.length == 0) return; + + this.listener.events.dispatchEvent(new RoomSessionErrorMessageEvent(type, roomSession)); + } +} diff --git a/src/nitro/session/handler/RoomChatHandler.ts b/src/nitro/session/handler/RoomChatHandler.ts new file mode 100644 index 00000000..966246a5 --- /dev/null +++ b/src/nitro/session/handler/RoomChatHandler.ts @@ -0,0 +1,116 @@ +import { IConnection } from '../../../core/communication/connections/IConnection'; +import { RespectReceivedEvent } from '../../communication/messages/incoming/notifications/RespectReceivedEvent'; +import { FloodControlEvent } from '../../communication/messages/incoming/room/unit/chat/FloodControlEvent'; +import { RemainingMuteEvent } from '../../communication/messages/incoming/room/unit/chat/RemainingMuteEvent'; +import { RoomUnitChatEvent } from '../../communication/messages/incoming/room/unit/chat/RoomUnitChatEvent'; +import { RoomUnitChatShoutEvent } from '../../communication/messages/incoming/room/unit/chat/RoomUnitChatShoutEvent'; +import { RoomUnitChatWhisperEvent } from '../../communication/messages/incoming/room/unit/chat/RoomUnitChatWhisperEvent'; +import { RoomUnitHandItemReceivedEvent } from '../../communication/messages/incoming/room/unit/RoomUnitHandItemReceivedEvent'; +import { SystemChatStyleEnum } from '../../ui/widget/enums/SystemChatStyleEnum'; +import { RoomSessionChatEvent } from '../events/RoomSessionChatEvent'; +import { IRoomHandlerListener } from '../IRoomHandlerListener'; +import { BaseHandler } from './BaseHandler'; + +export class RoomChatHandler extends BaseHandler +{ + constructor(connection: IConnection, listener: IRoomHandlerListener) + { + super(connection, listener); + + connection.addMessageEvent(new RoomUnitChatEvent(this.onRoomUnitChatEvent.bind(this))); + connection.addMessageEvent(new RoomUnitChatShoutEvent(this.onRoomUnitChatEvent.bind(this))); + connection.addMessageEvent(new RoomUnitChatWhisperEvent(this.onRoomUnitChatEvent.bind(this))); + connection.addMessageEvent(new RoomUnitHandItemReceivedEvent(this.onRoomUnitHandItemReceivedEvent.bind(this))); + connection.addMessageEvent(new RespectReceivedEvent(this.onRespectReceivedEvent.bind(this))); + connection.addMessageEvent(new FloodControlEvent(this.onFloodControlEvent.bind(this))); + connection.addMessageEvent(new RemainingMuteEvent(this.onRemainingMuteEvent.bind(this))); + } + + private onRoomUnitChatEvent(event: RoomUnitChatEvent): void + { + if(!this.listener) return; + + const session = this.listener.getSession(this.roomId); + + if(!session) return; + + const parser = event.getParser(); + + if(!parser) return; + + let chatType: number = RoomSessionChatEvent.CHAT_NORMAL; + + if(event instanceof RoomUnitChatShoutEvent) chatType = RoomSessionChatEvent.CHAT_SHOUT; + else if(event instanceof RoomUnitChatWhisperEvent) chatType = RoomSessionChatEvent.CHAT_WHISPER; + + const chatEvent = new RoomSessionChatEvent(RoomSessionChatEvent.CHAT_EVENT, session, parser.roomIndex, parser.message, chatType, parser.bubble); + + this.listener.events.dispatchEvent(chatEvent); + } + + private onRoomUnitHandItemReceivedEvent(event: RoomUnitHandItemReceivedEvent): void + { + if(!this.listener) return; + + const session = this.listener.getSession(this.roomId); + + if(!session) return; + + const parser = event.getParser(); + + if(!parser) return; + + this.listener.events.dispatchEvent(new RoomSessionChatEvent(RoomSessionChatEvent.CHAT_EVENT, session, parser.giverUserId, '', RoomSessionChatEvent._Str_8971, SystemChatStyleEnum.GENERIC, null, parser.handItemType)); + } + + private onRespectReceivedEvent(event: RespectReceivedEvent): void + { + if(!this.listener) return; + + const session = this.listener.getSession(this.roomId); + + if(!session) return; + + const parser = event.getParser(); + + if(!parser) return; + + const userData = session.userDataManager.getUserData(parser.userId); + + if(!userData) return; + + this.listener.events.dispatchEvent(new RoomSessionChatEvent(RoomSessionChatEvent.CHAT_EVENT, session, userData.roomIndex, '', RoomSessionChatEvent._Str_5821, SystemChatStyleEnum.GENERIC)); + } + + private onFloodControlEvent(event: FloodControlEvent): void + { + if(!this.listener) return; + + const session = this.listener.getSession(this.roomId); + + if(!session) return; + + const parser = event.getParser(); + + if(!parser) return; + + const seconds = parser.seconds; + + this.listener.events.dispatchEvent(new RoomSessionChatEvent(RoomSessionChatEvent.FLOOD_EVENT, session, -1, seconds.toString(), 0, 0)); + } + + private onRemainingMuteEvent(event: RemainingMuteEvent): void + { + if(!this.listener) return; + + const session = this.listener.getSession(this.roomId); + + if(!session) return; + + const parser = event.getParser(); + + if(!parser) return; + + this.listener.events.dispatchEvent(new RoomSessionChatEvent(RoomSessionChatEvent.CHAT_EVENT, session, session.ownRoomIndex, '', RoomSessionChatEvent._Str_8909, SystemChatStyleEnum.GENERIC, null, parser.seconds)); + } +} diff --git a/src/nitro/session/handler/RoomDataHandler.ts b/src/nitro/session/handler/RoomDataHandler.ts new file mode 100644 index 00000000..d96e6be8 --- /dev/null +++ b/src/nitro/session/handler/RoomDataHandler.ts @@ -0,0 +1,42 @@ +import { IConnection } from '../../../core/communication/connections/IConnection'; +import { RoomInfoEvent } from '../../communication/messages/incoming/room/data/RoomInfoEvent'; +import { RoomSessionEvent } from '../events/RoomSessionEvent'; +import { RoomSessionPropertyUpdateEvent } from '../events/RoomSessionPropertyUpdateEvent'; +import { IRoomHandlerListener } from '../IRoomHandlerListener'; +import { BaseHandler } from './BaseHandler'; + +export class RoomDataHandler extends BaseHandler +{ + constructor(connection: IConnection, listener: IRoomHandlerListener) + { + super(connection, listener); + + connection.addMessageEvent(new RoomInfoEvent(this.onRoomInfoEvent.bind(this))); + } + + private onRoomInfoEvent(event: RoomInfoEvent): void + { + if(!(event instanceof RoomInfoEvent)) return; + + const parser = event.getParser(); + + if(!parser) return; + + if(parser.roomForward) return; + + const roomSession = this.listener.getSession(this.roomId); + + if(!roomSession) return; + + const roomData = parser.data; + + roomSession.tradeMode = roomData.tradeMode; + roomSession.isGuildRoom = (roomData.habboGroupId !== 0); + roomSession.doorMode = roomData.doorMode; + roomSession.allowPets = roomData.allowPets; + roomSession.moderationSettings = parser.moderation; + + this.listener.events.dispatchEvent(new RoomSessionPropertyUpdateEvent(RoomSessionPropertyUpdateEvent.RSDUE_ALLOW_PETS, roomSession)); + this.listener.events.dispatchEvent(new RoomSessionEvent(RoomSessionEvent.ROOM_DATA, roomSession)); + } +} \ No newline at end of file diff --git a/src/nitro/session/handler/RoomDimmerPresetsHandler.ts b/src/nitro/session/handler/RoomDimmerPresetsHandler.ts new file mode 100644 index 00000000..c2eab628 --- /dev/null +++ b/src/nitro/session/handler/RoomDimmerPresetsHandler.ts @@ -0,0 +1,48 @@ +import { IConnection } from '../../../core/communication/connections/IConnection'; +import { RoomDimmerPresetsEvent } from '../../communication/messages/incoming/room/furniture/RoomDimmerPresetsMessageEvent'; +import { RoomSessionDimmerPresetsEvent } from '../events/RoomSessionDimmerPresetsEvent'; +import { IRoomHandlerListener } from '../IRoomHandlerListener'; +import { BaseHandler } from './BaseHandler'; + +export class RoomDimmerPresetsHandler extends BaseHandler +{ + constructor(connection: IConnection, listener: IRoomHandlerListener) + { + super(connection, listener); + + connection.addMessageEvent(new RoomDimmerPresetsEvent(this._Str_25786.bind(this))); + } + + private _Str_25786(k: RoomDimmerPresetsEvent): void + { + if(!k) return; + + const parser = k.getParser(); + + if(!parser) return; + + const session = this.listener.getSession(this.roomId); + + if(!session) return; + + const event = new RoomSessionDimmerPresetsEvent(RoomSessionDimmerPresetsEvent.RSDPE_PRESETS, session); + + event.selectedPresetId = parser._Str_6226; + + let i = 0; + + while(i < parser._Str_10888) + { + const preset = parser._Str_14989(i); + + if(preset) + { + event._Str_17287(preset.id, preset.type, preset.color, preset.intensity); + } + + i++; + } + + this.listener && this.listener.events.dispatchEvent(event); + } +} diff --git a/src/nitro/session/handler/RoomPermissionsHandler.ts b/src/nitro/session/handler/RoomPermissionsHandler.ts new file mode 100644 index 00000000..1767da09 --- /dev/null +++ b/src/nitro/session/handler/RoomPermissionsHandler.ts @@ -0,0 +1,52 @@ +import { IConnection } from '../../../core/communication/connections/IConnection'; +import { RoomRightsClearEvent } from '../../communication/messages/incoming/room/access/rights/RoomRightsClearEvent'; +import { RoomRightsEvent } from '../../communication/messages/incoming/room/access/rights/RoomRightsEvent'; +import { RoomRightsOwnerEvent } from '../../communication/messages/incoming/room/access/rights/RoomRightsOwnerEvent'; +import { RoomControllerLevel } from '../enum/RoomControllerLevel'; +import { IRoomHandlerListener } from '../IRoomHandlerListener'; +import { BaseHandler } from './BaseHandler'; + +export class RoomPermissionsHandler extends BaseHandler +{ + constructor(connection: IConnection, listener: IRoomHandlerListener) + { + super(connection, listener); + + connection.addMessageEvent(new RoomRightsEvent(this.onRoomRightsEvent.bind(this))); + connection.addMessageEvent(new RoomRightsClearEvent(this.onRoomRightsClearEvent.bind(this))); + connection.addMessageEvent(new RoomRightsOwnerEvent(this.onRoomRightsOwnerEvent.bind(this))); + } + + private onRoomRightsEvent(event: RoomRightsEvent): void + { + if(!(event instanceof RoomRightsEvent)) return; + + const session = this.listener.getSession(this.roomId); + + if(!session) return; + + session.setControllerLevel(event.getParser().controllerLevel); + } + + private onRoomRightsClearEvent(event: RoomRightsClearEvent): void + { + if(!(event instanceof RoomRightsClearEvent)) return; + + const session = this.listener.getSession(this.roomId); + + if(!session) return; + + session.setControllerLevel(RoomControllerLevel.NONE); + } + + private onRoomRightsOwnerEvent(event: RoomRightsOwnerEvent): void + { + if(!(event instanceof RoomRightsOwnerEvent)) return; + + const session = this.listener.getSession(this.roomId); + + if(!session) return; + + session.setRoomOwner(); + } +} \ No newline at end of file diff --git a/src/nitro/session/handler/RoomPresentHandler.ts b/src/nitro/session/handler/RoomPresentHandler.ts new file mode 100644 index 00000000..2b6de335 --- /dev/null +++ b/src/nitro/session/handler/RoomPresentHandler.ts @@ -0,0 +1,36 @@ +import { IConnection } from '../../../core/communication/connections/IConnection'; +import { IRoomHandlerListener } from '../IRoomHandlerListener'; +import { BaseHandler } from './BaseHandler'; +import { FurnitureGiftOpenedEvent } from '../../communication/messages/incoming/inventory/furni/gifts/FurnitureGiftOpenedEvent'; +import { RoomSessionPresentEvent } from '../events/RoomSessionPresentEvent'; + +export class RoomPresentHandler extends BaseHandler +{ + constructor(connection: IConnection, listener: IRoomHandlerListener) + { + super(connection, listener); + + if(!connection) return; + + connection.addMessageEvent(new FurnitureGiftOpenedEvent(this.onFurnitureGiftOpenedEvent.bind(this))); + } + + private onFurnitureGiftOpenedEvent(event: FurnitureGiftOpenedEvent): void + { + if(!event) return; + + const parser = event.getParser(); + + if(!parser) return; + + const session = this.listener.getSession(this.roomId); + + if(!session) return; + + if(this.listener && this.listener.events) this.listener.events.dispatchEvent( + new RoomSessionPresentEvent(RoomSessionPresentEvent.RSPE_PRESENT_OPENED, session, parser.classId, parser._Str_2887, + parser.productCode, parser.placedItemId, parser.placedItemType, parser._Str_4057, parser.petFigureString)); + + } + +} diff --git a/src/nitro/session/handler/RoomSessionHandler.ts b/src/nitro/session/handler/RoomSessionHandler.ts new file mode 100644 index 00000000..d837cf19 --- /dev/null +++ b/src/nitro/session/handler/RoomSessionHandler.ts @@ -0,0 +1,109 @@ +import { IConnection } from '../../../core/communication/connections/IConnection'; +import { DesktopViewEvent } from '../../communication/messages/incoming/desktop/DesktopViewEvent'; +import { RoomDoorbellAcceptedEvent } from '../../communication/messages/incoming/room/access/doorbell/RoomDoorbellAcceptedEvent'; +import { RoomDoorbellRejectedEvent } from '../../communication/messages/incoming/room/access/doorbell/RoomDoorbellRejectedEvent'; +import { RoomEnterEvent } from '../../communication/messages/incoming/room/access/RoomEnterEvent'; +import { RoomModelNameEvent } from '../../communication/messages/incoming/room/mapping/RoomModelNameEvent'; +import { RoomSessionDoorbellEvent } from '../events/RoomSessionDoorbellEvent'; +import { IRoomHandlerListener } from '../IRoomHandlerListener'; +import { BaseHandler } from './BaseHandler'; + +export class RoomSessionHandler extends BaseHandler +{ + public static RS_CONNECTED: string = 'RS_CONNECTED'; + public static RS_READY: string = 'RS_READY'; + public static RS_DISCONNECTED: string = 'RS_DISCONNECTED'; + + constructor(connection: IConnection, listener: IRoomHandlerListener) + { + super(connection, listener); + + connection.addMessageEvent(new RoomEnterEvent(this.onRoomEnterEvent.bind(this))); + connection.addMessageEvent(new RoomModelNameEvent(this.onRoomModelNameEvent.bind(this))); + connection.addMessageEvent(new DesktopViewEvent(this.onDesktopViewEvent.bind(this))); + connection.addMessageEvent(new RoomDoorbellAcceptedEvent(this.onRoomDoorbellAcceptedEvent.bind(this))); + connection.addMessageEvent(new RoomDoorbellRejectedEvent(this.onRoomDoorbellRejectedEvent.bind(this))); + } + + private onRoomEnterEvent(event: RoomEnterEvent): void + { + if(!(event instanceof RoomEnterEvent)) return; + + if(this.listener) this.listener.sessionUpdate(this.roomId, RoomSessionHandler.RS_CONNECTED); + } + + private onRoomModelNameEvent(event: RoomModelNameEvent): void + { + if(!(event instanceof RoomModelNameEvent)) return; + + const fromRoomId = this.roomId; + const toRoomId = event.getParser().roomId; + + if(this.listener) + { + this.listener.sessionReinitialize(fromRoomId, toRoomId); + this.listener.sessionUpdate(this.roomId, RoomSessionHandler.RS_READY); + } + } + + private onDesktopViewEvent(event: DesktopViewEvent): void + { + if(!(event instanceof DesktopViewEvent)) return; + + if(this.listener) this.listener.sessionUpdate(this.roomId, RoomSessionHandler.RS_DISCONNECTED); + } + + private onRoomDoorbellAcceptedEvent(event: RoomDoorbellAcceptedEvent): void + { + if(!(event instanceof RoomDoorbellAcceptedEvent) || !this.listener) return; + + const parser = event.getParser(); + + if(!parser) return; + + const username = parser.userName; + + if(!username || !username.length) + { + //this.connection.send(); + } + else + { + if(this.listener.events) + { + const session = this.listener.getSession(this.roomId); + + if(!session) return; + + this.listener.events.dispatchEvent(new RoomSessionDoorbellEvent(RoomSessionDoorbellEvent.RSDE_ACCEPTED, session, username)); + } + } + } + + private onRoomDoorbellRejectedEvent(event: RoomDoorbellRejectedEvent): void + { + if(!(event instanceof RoomDoorbellRejectedEvent) || !this.listener) return; + + const parser = event.getParser(); + + if(!parser) return; + + const username = parser.userName; + + if(!username || !username.length) + { + this.listener.sessionUpdate(this.roomId, RoomSessionHandler.RS_DISCONNECTED); + } + else + { + if(this.listener.events) + { + const session = this.listener.getSession(this.roomId); + + if(!session) return; + + this.listener.events.dispatchEvent(new RoomSessionDoorbellEvent(RoomSessionDoorbellEvent.RSDE_REJECTED, session, username)); + } + } + } +} \ No newline at end of file diff --git a/src/nitro/session/handler/RoomUsersHandler.ts b/src/nitro/session/handler/RoomUsersHandler.ts new file mode 100644 index 00000000..7b0e3ed7 --- /dev/null +++ b/src/nitro/session/handler/RoomUsersHandler.ts @@ -0,0 +1,332 @@ +import { IConnection } from '../../../core/communication/connections/IConnection'; +import { NewFriendRequestEvent } from '../../communication/messages/incoming/friendlist/NewFriendRequestEvent'; +import { BotErrorEvent } from '../../communication/messages/incoming/notifications/BotErrorEvent'; +import { PetPlacingErrorEvent } from '../../communication/messages/incoming/notifications/PetPlacingErrorEvent'; +import { RoomDoorbellEvent } from '../../communication/messages/incoming/room/access/doorbell/RoomDoorbellEvent'; +import { PetInfoEvent } from '../../communication/messages/incoming/room/pet/PetInfoEvent'; +import { RoomUnitDanceEvent } from '../../communication/messages/incoming/room/unit/RoomUnitDanceEvent'; +import { RoomUnitEvent } from '../../communication/messages/incoming/room/unit/RoomUnitEvent'; +import { RoomUnitInfoEvent } from '../../communication/messages/incoming/room/unit/RoomUnitInfoEvent'; +import { RoomUnitRemoveEvent } from '../../communication/messages/incoming/room/unit/RoomUnitRemoveEvent'; +import { UserCurrentBadgesEvent } from '../../communication/messages/incoming/user/data/UserCurrentBadgesEvent'; +import { UserNameChangeMessageEvent } from '../../communication/messages/incoming/user/data/UserNameChangeMessageEvent'; +import { RoomSessionDanceEvent } from '../events/RoomSessionDanceEvent'; +import { RoomSessionDoorbellEvent } from '../events/RoomSessionDoorbellEvent'; +import { RoomSessionErrorMessageEvent } from '../events/RoomSessionErrorMessageEvent'; +import { RoomSessionFriendRequestEvent } from '../events/RoomSessionFriendRequestEvent'; +import { RoomSessionPetInfoUpdateEvent } from '../events/RoomSessionPetInfoUpdateEvent'; +import { RoomSessionUserBadgesEvent } from '../events/RoomSessionUserBadgesEvent'; +import { RoomSessionUserDataUpdateEvent } from '../events/RoomSessionUserDataUpdateEvent'; +import { IRoomHandlerListener } from '../IRoomHandlerListener'; +import { RoomPetData } from '../RoomPetData'; +import { RoomUserData } from '../RoomUserData'; +import { BaseHandler } from './BaseHandler'; + +export class RoomUsersHandler extends BaseHandler +{ + constructor(connection: IConnection, listener: IRoomHandlerListener) + { + super(connection, listener); + + connection.addMessageEvent(new RoomUnitEvent(this.onRoomUnitEvent.bind(this))); + connection.addMessageEvent(new RoomUnitInfoEvent(this.onRoomUnitInfoEvent.bind(this))); + connection.addMessageEvent(new RoomUnitRemoveEvent(this.onRoomUnitRemoveEvent.bind(this))); + connection.addMessageEvent(new RoomUnitDanceEvent(this.onRoomUnitDanceEvent.bind(this))); + connection.addMessageEvent(new UserCurrentBadgesEvent(this.onUserCurrentBadgesEvent.bind(this))); + connection.addMessageEvent(new RoomDoorbellEvent(this.onRoomDoorbellEvent.bind(this))); + connection.addMessageEvent(new UserNameChangeMessageEvent(this.onUserNameChangeMessageEvent.bind(this))); + connection.addMessageEvent(new NewFriendRequestEvent(this.onNewFriendRequestEvent.bind(this))); + connection.addMessageEvent(new PetInfoEvent(this.onPetInfoEvent.bind(this))); + connection.addMessageEvent(new PetPlacingErrorEvent(this.onPetPlacingError.bind(this))); + connection.addMessageEvent(new BotErrorEvent(this.onBotError.bind(this))); + } + + private onRoomUnitEvent(event: RoomUnitEvent): void + { + if(!this.listener) return; + + const session = this.listener.getSession(this.roomId); + + if(!session) return; + + const users = event.getParser().users; + + const usersToAdd: RoomUserData[] = []; + + if(users && users.length) + { + for(const user of users) + { + if(!user) continue; + + const userData = new RoomUserData(user.roomIndex); + + userData.name = user.name; + userData.custom = user.custom; + userData.activityPoints = user.activityPoints; + userData.figure = user.figure; + userData.type = user.userType; + userData.webID = user.webID; + userData.guildId = user.groupID; + userData.groupName = user.groupName; + userData.groupStatus = user.groupStatus; + userData.sex = user.sex; + userData.ownerId = user.ownerId; + userData.ownerName = user.ownerName; + userData.rarityLevel = user.rarityLevel; + userData.hasSaddle = user.hasSaddle; + userData.isRiding = user.isRiding; + userData.canBreed = user.canBreed; + userData.canHarvest = user.canHarvest; + userData.canRevive = user.canRevive; + userData.hasBreedingPermission = user.hasBreedingPermission; + userData.petLevel = user.petLevel; + userData.botSkills = user.botSkills; + userData.isModerator = user.isModerator; + + if(!session.userDataManager.getUserData(user.roomIndex)) usersToAdd.push(userData); + + session.userDataManager.updateUserData(userData); + } + } + + this.listener.events.dispatchEvent(new RoomSessionUserDataUpdateEvent(session, usersToAdd)); + } + + private onRoomUnitInfoEvent(event: RoomUnitInfoEvent): void + { + if(!this.listener) return; + + const session = this.listener.getSession(this.roomId); + + if(!session) return; + + const parser = event.getParser(); + + if(!parser) return; + + session.userDataManager.updateFigure(parser.unitId, parser.figure, parser.gender, false, false); + session.userDataManager.updateMotto(parser.unitId, parser.motto); + } + + private onRoomUnitRemoveEvent(event: RoomUnitRemoveEvent): void + { + if(!this.listener) return; + + const session = this.listener.getSession(this.roomId); + + if(!session) return; + + session.userDataManager.removeUserData(event.getParser().unitId); + } + + private onRoomUnitDanceEvent(event: RoomUnitDanceEvent): void + { + if(!this.listener) return; + + const parser = event.getParser(); + + if(!parser) return; + + const session = this.listener.getSession(this.roomId); + + if(!session) return; + + this.listener.events.dispatchEvent(new RoomSessionDanceEvent(session, parser.unitId, parser.danceId)); + } + + private onUserCurrentBadgesEvent(event: UserCurrentBadgesEvent): void + { + if(!this.listener) return; + + const parser = event.getParser(); + + if(!parser) return; + + const session = this.listener.getSession(this.roomId); + + if(!session) return; + + session.userDataManager.setUserBadges(parser.userId, parser.badges); + + this.listener.events.dispatchEvent(new RoomSessionUserBadgesEvent(session, parser.userId, parser.badges)); + } + + private onRoomDoorbellEvent(event: RoomDoorbellEvent): void + { + if(!this.listener) return; + + const parser = event.getParser(); + + if(!parser) return; + + const username = parser.userName; + + if(!username || !username.length) return; + + const session = this.listener.getSession(this.roomId); + + if(!session) return; + + this.listener.events.dispatchEvent(new RoomSessionDoorbellEvent(RoomSessionDoorbellEvent.DOORBELL, session, username)); + } + + private onUserNameChangeMessageEvent(event: UserNameChangeMessageEvent): void + { + if(!this.listener) return; + + const parser = event.getParser(); + + if(!parser) return; + + const session = this.listener.getSession(this.roomId); + + if(!session) return; + + session.userDataManager.updateName(parser.id, parser.newName); + } + + private onNewFriendRequestEvent(event: NewFriendRequestEvent): void + { + if(!this.listener) return; + + const parser = event.getParser(); + + if(!parser) return; + + const session = this.listener.getSession(this.roomId); + + if(!session) return; + + const request = parser.request; + + this.listener.events.dispatchEvent(new RoomSessionFriendRequestEvent(session, request.requestId, request.requesterUserId, request.requesterName)); + } + + private onPetInfoEvent(event: PetInfoEvent): void + { + if(!this.listener) return; + + const parser = event.getParser(); + + if(!parser) return; + + const session = this.listener.getSession(this.roomId); + + if(!session) return; + + const petData = new RoomPetData(); + + petData.id = parser.id; + petData.level = parser.level; + petData.maximumLevel = parser.maximumLevel; + petData.experience = parser.experience; + petData.levelExperienceGoal = parser.levelExperienceGoal; + petData.energy = parser.energy; + petData.maximumEnergy = parser.maximumEnergy; + petData.happyness = parser.happyness; + petData.maximumHappyness = parser.maximumHappyness; + petData.ownerId = parser.ownerId; + petData.ownerName = parser.ownerName; + petData.respect = parser.respect; + petData.age = parser.age; + petData.unknownRarity = parser.unknownRarity; + petData.saddle = parser.saddle; + petData.rider = parser.rider; + petData.breedable = parser.breedable; + petData.fullyGrown = parser.fullyGrown; + petData.rarityLevel = parser.rarityLevel; + petData.dead = parser.dead; + petData._Str_3307 = parser._Str_3307; + petData.publiclyRideable = parser.publiclyRideable; + petData.maximumTimeToLive = parser.maximumTimeToLive; + petData.remainingTimeToLive = parser.remainingTimeToLive; + petData.remainingGrowTime = parser.remainingGrowTime; + petData.publiclyBreedable = parser.publiclyBreedable; + + this.listener.events.dispatchEvent(new RoomSessionPetInfoUpdateEvent(session, petData)); + } + + private onPetPlacingError(event: PetPlacingErrorEvent): void + { + if(!event) return; + + if(!this.listener) return; + + const parser = event.getParser(); + + if(!parser) return; + + const session = this.listener.getSession(this.roomId); + + if(!session) return; + + let type: string = null; + + switch(parser.errorCode) + { + case 0: + type = RoomSessionErrorMessageEvent.RSEME_PETS_FORBIDDEN_IN_HOTEL; + break; + case 1: + type = RoomSessionErrorMessageEvent.RSEME_PETS_FORBIDDEN_IN_FLAT; + break; + case 2: + type = RoomSessionErrorMessageEvent.RSEME_MAX_PETS; + break; + case 3: + type = RoomSessionErrorMessageEvent.RSEME_NO_FREE_TILES_FOR_PET; + break; + case 4: + type = RoomSessionErrorMessageEvent.RSEME_SELECTED_TILE_NOT_FREE_FOR_PET; + break; + case 5: + type = RoomSessionErrorMessageEvent.RSEME_MAX_NUMBER_OF_OWN_PETS; + break; + } + + if(!type || type.length == 0) return; + + this.listener.events.dispatchEvent(new RoomSessionErrorMessageEvent(type, session)); + } + + private onBotError(event: BotErrorEvent): void + { + if(!event) return; + + if(!this.listener) return; + + const parser = event.getParser(); + + if(!parser) return; + + const session = this.listener.getSession(this.roomId); + + if(!session) return; + + let type: string = null; + + switch(parser.errorCode) + { + case 0: + type = RoomSessionErrorMessageEvent.RSEME_BOTS_FORBIDDEN_IN_HOTEL; + break; + case 1: + type = RoomSessionErrorMessageEvent.RSEME_BOTS_FORBIDDEN_IN_FLAT; + break; + case 2: + type = RoomSessionErrorMessageEvent.RSEME_BOT_LIMIT_REACHED; + break; + case 3: + type = RoomSessionErrorMessageEvent.RSEME_SELECTED_TILE_NOT_FREE_FOR_BOT; + break; + case 4: + type = RoomSessionErrorMessageEvent.RSEME_BOT_NAME_NOT_ACCEPTED; + break; + } + + if(!type || type.length == 0) return; + + this.listener.events.dispatchEvent(new RoomSessionErrorMessageEvent(type, session)); + } +} diff --git a/src/nitro/session/product/IProductData.ts b/src/nitro/session/product/IProductData.ts new file mode 100644 index 00000000..95cf4d18 --- /dev/null +++ b/src/nitro/session/product/IProductData.ts @@ -0,0 +1,6 @@ +export interface IProductData +{ + type: string; + name: string; + description: string; +} diff --git a/src/nitro/session/product/IProductDataListener.ts b/src/nitro/session/product/IProductDataListener.ts new file mode 100644 index 00000000..81aa76f9 --- /dev/null +++ b/src/nitro/session/product/IProductDataListener.ts @@ -0,0 +1,6 @@ +import { IDisposable } from '../../../core/common/disposable/IDisposable'; + +export interface IProductDataListener extends IDisposable +{ + loadProductData(): void; +} diff --git a/src/nitro/session/product/ProductData.ts b/src/nitro/session/product/ProductData.ts new file mode 100644 index 00000000..f1754ee1 --- /dev/null +++ b/src/nitro/session/product/ProductData.ts @@ -0,0 +1,30 @@ +import { IProductData } from './IProductData'; + +export class ProductData implements IProductData +{ + private _type: string; + private _name: string; + private _description: string; + + constructor(type: string, name: string, description: string) + { + this._type = type; + this._name = name; + this._description = description; + } + + public get type(): string + { + return this._type; + } + + public get name(): string + { + return this._name; + } + + public get description(): string + { + return this._description; + } +} diff --git a/src/nitro/session/product/ProductDataParser.ts b/src/nitro/session/product/ProductDataParser.ts new file mode 100644 index 00000000..90af13de --- /dev/null +++ b/src/nitro/session/product/ProductDataParser.ts @@ -0,0 +1,57 @@ +import { EventDispatcher } from '../../../core/events/EventDispatcher'; +import { NitroEvent } from '../../../core/events/NitroEvent'; +import { IProductData } from './IProductData'; +import { ProductData } from './ProductData'; + +export class ProductDataParser extends EventDispatcher +{ + public static PDP_PRODUCT_DATA_READY: string = 'PDP_PRODUCT_DATA_READY'; + public static PDP_PRODUCT_DATA_FAILED: string = 'PDP_PRODUCT_DATA_FAILED'; + + private _products: Map; + + constructor(products: Map) + { + super(); + + this._products = products; + } + + public dispose(): void + { + this._products = null; + } + + public loadProductData(url: string): void + { + if(!url) return; + + fetch(url) + .then(response => response.json()) + .then(data => this.onProductDataLoadedEvent(data)) + .catch(err => this.onProductDataError(err)); + } + + private onProductDataLoadedEvent(data: { [index: string]: any }): void + { + if(!data) return; + + this.parseProducts(data.productdata); + + this.dispatchEvent(new NitroEvent(ProductDataParser.PDP_PRODUCT_DATA_READY)); + } + + private onProductDataError(error: Error): void + { + if(!error) return; + + this.dispatchEvent(new NitroEvent(ProductDataParser.PDP_PRODUCT_DATA_FAILED)); + } + + private parseProducts(data: { [index: string]: any }): void + { + if(!data) return; + + for(const product of data.product) (product && this._products.set(product.code, new ProductData(product.code, product.name, product.description))); + } +} diff --git a/src/nitro/ui/IRoomWidgetHandler.ts b/src/nitro/ui/IRoomWidgetHandler.ts new file mode 100644 index 00000000..8256ed7b --- /dev/null +++ b/src/nitro/ui/IRoomWidgetHandler.ts @@ -0,0 +1,16 @@ +import { IDisposable } from '../../core/common/disposable/IDisposable'; +import { NitroEvent } from '../../core/events/NitroEvent'; +import { IRoomWidgetHandlerContainer } from './IRoomWidgetHandlerContainer'; +import { RoomWidgetUpdateEvent } from './widget/events/RoomWidgetUpdateEvent'; +import { RoomWidgetMessage } from './widget/messages/RoomWidgetMessage'; + +export interface IRoomWidgetHandler extends IDisposable +{ + update(): void; + processWidgetMessage(message: RoomWidgetMessage): RoomWidgetUpdateEvent; + processEvent(event: NitroEvent): void; + type: string; + messageTypes: string[]; + eventTypes: string[]; + container: IRoomWidgetHandlerContainer; +} \ No newline at end of file diff --git a/src/nitro/ui/IRoomWidgetHandlerContainer.ts b/src/nitro/ui/IRoomWidgetHandlerContainer.ts new file mode 100644 index 00000000..3d1268de --- /dev/null +++ b/src/nitro/ui/IRoomWidgetHandlerContainer.ts @@ -0,0 +1,27 @@ +import { Rectangle } from 'pixi.js'; +import { IConnection } from '../../core/communication/connections/IConnection'; +import { IEventDispatcher } from '../../core/events/IEventDispatcher'; +import { IRoomObject } from '../../room/object/IRoomObject'; +import { IAvatarRenderManager } from '../avatar/IAvatarRenderManager'; +import { IRoomEngine } from '../room/IRoomEngine'; +import { IRoomSession } from '../session/IRoomSession'; +import { IRoomSessionManager } from '../session/IRoomSessionManager'; +import { ISessionDataManager } from '../session/ISessionDataManager'; +import { RoomWidgetUpdateEvent } from './widget/events/RoomWidgetUpdateEvent'; +import { RoomWidgetMessage } from './widget/messages/RoomWidgetMessage'; + +export interface IRoomWidgetHandlerContainer +{ + getFirstCanvasId(): number; + getRoomViewRect(): Rectangle; + checkFurniManipulationRights(roomId: number, objectId: number, category: number): boolean; + isOwnerOfFurniture(roomObject: IRoomObject): boolean; + processWidgetMessage(message: RoomWidgetMessage): RoomWidgetUpdateEvent; + events: IEventDispatcher; + connection: IConnection; + roomEngine: IRoomEngine; + avatarRenderManager: IAvatarRenderManager; + roomSession: IRoomSession; + roomSessionManager: IRoomSessionManager; + sessionDataManager: ISessionDataManager; +} diff --git a/src/nitro/ui/MouseEventType.ts b/src/nitro/ui/MouseEventType.ts new file mode 100644 index 00000000..4d5c7f19 --- /dev/null +++ b/src/nitro/ui/MouseEventType.ts @@ -0,0 +1,10 @@ +export class MouseEventType +{ + public static MOUSE_CLICK: string = 'click'; + public static DOUBLE_CLICK: string = 'double_click'; + public static MOUSE_MOVE: string = 'mousemove'; + public static MOUSE_DOWN: string = 'mousedown'; + public static MOUSE_UP: string = 'mouseup'; + public static ROLL_OVER: string = 'mouseover'; + public static ROLL_OUT: string = 'mouseout'; +} \ No newline at end of file diff --git a/src/nitro/ui/TouchEventType.ts b/src/nitro/ui/TouchEventType.ts new file mode 100644 index 00000000..4f903421 --- /dev/null +++ b/src/nitro/ui/TouchEventType.ts @@ -0,0 +1,7 @@ +export class TouchEventType +{ + public static TOUCH_START: string = 'touchstart'; + public static TOUCH_MOVE: string = 'touchmove'; + public static TOUCH_CANCEL: string = 'touchcancel'; + public static TOUCH_END: string = 'touchend'; +} \ No newline at end of file diff --git a/src/nitro/ui/widget/ConversionTrackingWidget.ts b/src/nitro/ui/widget/ConversionTrackingWidget.ts new file mode 100644 index 00000000..7105cc63 --- /dev/null +++ b/src/nitro/ui/widget/ConversionTrackingWidget.ts @@ -0,0 +1,85 @@ +import { IEventDispatcher } from '../../../core/events/IEventDispatcher'; +import { IRoomWidgetHandler } from '../IRoomWidgetHandler'; +import { IRoomWidget } from './IRoomWidget'; +import { IRoomWidgetMessageListener } from './IRoomWidgetMessageListener'; + +export class ConversionTrackingWidget implements IRoomWidget +{ + private _widgetHandler: IRoomWidgetHandler; + private _messageListener: IRoomWidgetMessageListener; + private _events: IEventDispatcher; + private _disposed: boolean; + + constructor() + { + this._widgetHandler = null; + this._messageListener = null; + this._events = null; + this._disposed = false; + } + + public initialize(k: number = 0): void + { + + } + + public dispose(): void + { + if(this.disposed) return; + + this._messageListener = null; + + if(this._events && !this._events.disposed) + { + this.unregisterUpdateEvents(this._events); + } + + if(this._widgetHandler) + { + this._widgetHandler.dispose(); + + this._widgetHandler = null; + } + + this._events = null; + this._disposed = true; + } + + public registerUpdateEvents(eventDispatcher: IEventDispatcher): void + { + this._events = eventDispatcher; + } + + public unregisterUpdateEvents(eventDispatcher: IEventDispatcher): void + { + this._events = null; + } + + public get disposed(): boolean + { + return this._disposed; + } + + public get widgetHandler(): IRoomWidgetHandler + { + return this._widgetHandler; + } + + public set widgetHandler(handler: IRoomWidgetHandler) + { + this._widgetHandler = handler; + + //@ts-ignore + if(!this._widgetHandler.widget) this._widgetHandler.widget = this; + } + + public get messageListener(): IRoomWidgetMessageListener + { + return this._messageListener; + } + + public set messageListener(listener: IRoomWidgetMessageListener) + { + this._messageListener = listener; + } +} \ No newline at end of file diff --git a/src/nitro/ui/widget/IRoomWidget.ts b/src/nitro/ui/widget/IRoomWidget.ts new file mode 100644 index 00000000..b549ce23 --- /dev/null +++ b/src/nitro/ui/widget/IRoomWidget.ts @@ -0,0 +1,13 @@ +import { IEventDispatcher } from '../../../core/events/IEventDispatcher'; +import { IRoomWidgetHandler } from '../IRoomWidgetHandler'; +import { IRoomWidgetMessageListener } from './IRoomWidgetMessageListener'; + +export interface IRoomWidget +{ + initialize(_arg_1?: number): void; + dispose(): void; + registerUpdateEvents(eventDispatcher: IEventDispatcher): void; + unregisterUpdateEvents(eventDispatcher: IEventDispatcher): void; + widgetHandler: IRoomWidgetHandler; + messageListener: IRoomWidgetMessageListener; +} \ No newline at end of file diff --git a/src/nitro/ui/widget/IRoomWidgetMessageListener.ts b/src/nitro/ui/widget/IRoomWidgetMessageListener.ts new file mode 100644 index 00000000..c3d0b74e --- /dev/null +++ b/src/nitro/ui/widget/IRoomWidgetMessageListener.ts @@ -0,0 +1,7 @@ +import { RoomWidgetUpdateEvent } from './events/RoomWidgetUpdateEvent'; +import { RoomWidgetMessage } from './messages/RoomWidgetMessage'; + +export interface IRoomWidgetMessageListener +{ + processWidgetMessage(message: RoomWidgetMessage): RoomWidgetUpdateEvent; +} \ No newline at end of file diff --git a/src/nitro/ui/widget/enums/AvatarExpressionEnum.ts b/src/nitro/ui/widget/enums/AvatarExpressionEnum.ts new file mode 100644 index 00000000..767d05a3 --- /dev/null +++ b/src/nitro/ui/widget/enums/AvatarExpressionEnum.ts @@ -0,0 +1,28 @@ +export class AvatarExpressionEnum +{ + public static NONE: AvatarExpressionEnum = new AvatarExpressionEnum(0); + public static _Str_6268: AvatarExpressionEnum = new AvatarExpressionEnum(1); + public static _Str_5579: AvatarExpressionEnum = new AvatarExpressionEnum(2); + public static _Str_7336: AvatarExpressionEnum = new AvatarExpressionEnum(3); + public static _Str_10353: AvatarExpressionEnum = new AvatarExpressionEnum(4); + public static _Str_6989: AvatarExpressionEnum = new AvatarExpressionEnum(5); + public static _Str_16682: AvatarExpressionEnum = new AvatarExpressionEnum(6); + public static _Str_6325: AvatarExpressionEnum = new AvatarExpressionEnum(7); + + private _ordinal: number; + + constructor(k: number) + { + this._ordinal = k; + } + + public get _Str_6677(): number + { + return this._ordinal; + } + + public _Str_1451(k: AvatarExpressionEnum): boolean + { + return (k) && (k._ordinal == this._ordinal); + } +} \ No newline at end of file diff --git a/src/nitro/ui/widget/enums/FriendWidgetEngravingWidgetTypeEnum.ts b/src/nitro/ui/widget/enums/FriendWidgetEngravingWidgetTypeEnum.ts new file mode 100644 index 00000000..44176878 --- /dev/null +++ b/src/nitro/ui/widget/enums/FriendWidgetEngravingWidgetTypeEnum.ts @@ -0,0 +1,8 @@ +export class FriendWidgetEngravingWidgetTypeEnum +{ + public static LOVE_LOCK: number = 0; + public static CARVE_A_TREE: number = 1; + public static FRIENDS_PORTRAIT: number = 2; + public static WILD_WEST_WANTED: number = 3; + public static HABBOWEEN: number = 4; +} diff --git a/src/nitro/ui/widget/enums/RoomWidgetEnum.ts b/src/nitro/ui/widget/enums/RoomWidgetEnum.ts new file mode 100644 index 00000000..8b1ff827 --- /dev/null +++ b/src/nitro/ui/widget/enums/RoomWidgetEnum.ts @@ -0,0 +1,57 @@ +export class RoomWidgetEnum +{ + public static CHAT_WIDGET: string = 'RWE_CHAT_WIDGET'; + public static INFOSTAND: string = 'RWE_INFOSTAND'; + public static ME_MENU: string = 'RWE_ME_MENU'; + public static CHAT_INPUT_WIDGET: string = 'RWE_CHAT_INPUT_WIDGET'; + public static FURNI_PLACEHOLDER: string = 'RWE_FURNI_PLACEHOLDER'; + public static FURNI_CREDIT_WIDGET: string = 'RWE_FURNI_CREDIT_WIDGET'; + public static FURNI_STICKIE_WIDGET: string = 'RWE_FURNI_STICKIE_WIDGET'; + public static FURNI_TROPHY_WIDGET: string = 'RWE_FURNI_TROPHY_WIDGET'; + public static FURNI_LOVELOCK_WIDGET: string = 'RWE_FURNI_LOVELOCK_WIDGET'; + public static FURNI_PRESENT_WIDGET: string = 'RWE_FURNI_PRESENT_WIDGET'; + public static FURNI_ECOTRONBOX_WIDGET: string = 'RWE_FURNI_ECOTRONBOX_WIDGET'; + public static FURNI_PET_PACKAGE_WIDGET: string = 'RWE_FURNI_PET_PACKAGE_WIDGET'; + public static PLAYLIST_EDITOR_WIDGET: string = 'RWE_PLAYLIST_EDITOR_WIDGET'; + public static DOORBELL: string = 'RWE_DOORBELL'; + public static LOADINGBAR: string = 'RWE_LOADINGBAR'; + public static ROOM_QUEUE: string = 'RWE_ROOM_QUEUE'; + public static ROOM_POLL: string = 'RWE_ROOM_POLL'; + public static ROOM_VOTE: string = 'RWE_ROOM_VOTE'; + public static USER_CHOOSER: string = 'RWE_USER_CHOOSER'; + public static FURNI_CHOOSER: string = 'RWE_FURNI_CHOOSER'; + public static ROOM_DIMMER: string = 'RWE_ROOM_DIMMER'; + public static FRIEND_REQUEST: string = 'RWE_FRIEND_REQUEST'; + public static CLOTHING_CHANGE: string = 'RWE_CLOTHING_CHANGE'; + public static CONVERSION_TRACKING: string = 'RWE_CONVERSION_TRACKING'; + public static USER_NOTIFICATION: string = 'RWE_USER_NOTIFICATION'; + public static FRIENDS_BAR: string = 'RWE_FRIENDS_BAR'; + public static PURSE_WIDGET: string = 'RWE_PURSE_WIDGET'; + public static AVATAR_INFO: string = 'RWE_AVATAR_INFO'; + public static WELCOME_GIFT: string = 'RWE_WELCOME_GIFT'; + public static SPAMWALL_POSTIT_WIDGET: string = 'RWE_SPAMWALL_POSTIT_WIDGET'; + public static EFFECTS: string = 'RWE_EFFECTS'; + public static MANNEQUIN: string = 'RWE_MANNEQUIN'; + public static FURNITURE_CONTEXT_MENU: string = 'RWE_FURNITURE_CONTEXT_MENU'; + public static LOCATION_WIDGET: string = 'RWE_LOCATION_WIDGET'; + public static CAMERA: string = 'RWE_CAMERA'; + public static ROOM_THUMBNAIL_CAMERA: string = 'RWE_ROOM_THUMBNAIL_CAMERA'; + public static ROOM_BACKGROUND_COLOR: string = 'RWE_ROOM_BACKGROUND_COLOR'; + public static CUSTOM_USER_NOTIFICATION: string = 'RWE_CUSTOM_USER_NOTIFICATION'; + public static FURNI_ACHIEVEMENT_RESOLUTION_ENGRAVING: string = 'RWE_FURNI_ACHIEVEMENT_RESOLUTION_ENGRAVING'; + public static FRIEND_FURNI_CONFIRM: string = 'RWE_FRIEND_FURNI_CONFIRM'; + public static FRIEND_FURNI_ENGRAVING: string = 'RWE_FRIEND_FURNI_ENGRAVING'; + public static HIGH_SCORE_DISPLAY: string = 'RWE_HIGH_SCORE_DISPLAY'; + public static INTERNAL_LINK: string = 'RWE_INTERNAL_LINK'; + public static CUSTOM_STACK_HEIGHT: string = 'RWE_CUSTOM_STACK_HEIGHT'; + public static YOUTUBE: string = 'RWE_YOUTUBE'; + public static RENTABLESPACE: string = 'RWE_RENTABLESPACE'; + public static VIMEO: string = 'RWE_VIMEO'; + public static ROOM_TOOLS: string = 'RWE_ROOM_TOOLS'; + public static EXTERNAL_IMAGE: string = 'RWE_EXTERNAL_IMAGE'; + public static WORD_QUIZZ: string = 'RWE_WORD_QUIZZ'; + public static UI_HELP_BUBBLE: string = 'RWE_UI_HELP_BUBBLE'; + public static ROOM_LINK: string = 'RWE_ROOM_LINK'; + public static CRAFTING: string = 'RWE_CRAFTING'; + public static ROOMGAME_CHECKERS: string = 'RWE_GAME_CHECKERS'; +} diff --git a/src/nitro/ui/widget/enums/RoomWidgetEnumItemExtradataParameter.ts b/src/nitro/ui/widget/enums/RoomWidgetEnumItemExtradataParameter.ts new file mode 100644 index 00000000..d252e69e --- /dev/null +++ b/src/nitro/ui/widget/enums/RoomWidgetEnumItemExtradataParameter.ts @@ -0,0 +1,10 @@ +export class RoomWidgetEnumItemExtradataParameter +{ + public static INFOSTAND_EXTRA_PARAM: string = 'RWEIEP_INFOSTAND_EXTRA_PARAM'; + public static JUKEBOX: string = 'RWEIEP_JUKEBOX'; + public static USABLE_PRODUCT: string = 'RWEIEP_USABLE_PRODUCT'; + public static SONGDISK: string = 'RWEIEP_SONGDISK'; + public static CRACKABLE_FURNI: string = 'RWEIEP_CRACKABLE_FURNI'; + public static BRANDING_OPTIONS: string = 'RWEIEP_BRANDING_OPTIONS'; + public static USABLE: string = 'RWEIEP_USABLE'; +} diff --git a/src/nitro/ui/widget/enums/RoomWidgetFurniInfoUsagePolicyEnum.ts b/src/nitro/ui/widget/enums/RoomWidgetFurniInfoUsagePolicyEnum.ts new file mode 100644 index 00000000..ee2fa451 --- /dev/null +++ b/src/nitro/ui/widget/enums/RoomWidgetFurniInfoUsagePolicyEnum.ts @@ -0,0 +1,6 @@ +export class RoomWidgetFurniInfoUsagePolicyEnum +{ + public static _Str_21805: number = 0; + public static _Str_18194: number = 1; + public static _Str_18353: number = 2; +} \ No newline at end of file diff --git a/src/nitro/ui/widget/enums/SystemChatStyleEnum.ts b/src/nitro/ui/widget/enums/SystemChatStyleEnum.ts new file mode 100644 index 00000000..f49f8804 --- /dev/null +++ b/src/nitro/ui/widget/enums/SystemChatStyleEnum.ts @@ -0,0 +1,6 @@ +export class SystemChatStyleEnum +{ + public static NORMAL: number = 0; + public static GENERIC: number = 1; + public static BOT: number = 2; +} \ No newline at end of file diff --git a/src/nitro/ui/widget/events/RoomWidgetUpdateEvent.ts b/src/nitro/ui/widget/events/RoomWidgetUpdateEvent.ts new file mode 100644 index 00000000..be3aa8df --- /dev/null +++ b/src/nitro/ui/widget/events/RoomWidgetUpdateEvent.ts @@ -0,0 +1,9 @@ +import { NitroEvent } from '../../../../core/events/NitroEvent'; + +export class RoomWidgetUpdateEvent extends NitroEvent +{ + constructor(type: string) + { + super(type); + } +} \ No newline at end of file diff --git a/src/nitro/ui/widget/messages/RoomWidgetMessage.ts b/src/nitro/ui/widget/messages/RoomWidgetMessage.ts new file mode 100644 index 00000000..4f201426 --- /dev/null +++ b/src/nitro/ui/widget/messages/RoomWidgetMessage.ts @@ -0,0 +1,14 @@ +export class RoomWidgetMessage +{ + private _type: string; + + constructor(type: string) + { + this._type = type; + } + + public get type(): string + { + return this._type; + } +} \ No newline at end of file diff --git a/src/nitro/utils/FigureDataContainer.ts b/src/nitro/utils/FigureDataContainer.ts new file mode 100644 index 00000000..96f666e8 --- /dev/null +++ b/src/nitro/utils/FigureDataContainer.ts @@ -0,0 +1,241 @@ +export class FigureDataContainer +{ + private static M: string = 'M'; + private static F: string = 'F'; + private static U: string = 'U'; + private static H: string = 'h'; + private static STD: string = 'std'; + private static _Str_2028: string = '0'; + private static HD: string = 'hd'; + private static HR: string = 'hr'; + private static HA: string = 'ha'; + private static HE: string = 'he'; + private static EA: string = 'ea'; + private static FA: string = 'fa'; + private static CC: string = 'cc'; + private static CH: string = 'ch'; + private static CA: string = 'ca'; + private static CP: string = 'cp'; + private static LG: string = 'lg'; + private static SH: string = 'sh'; + private static WA: string = 'wa'; + private static _Str_1329: number[] = [28, 29, 30, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 68]; + + private _data: Map; + private _colors: Map; + private _gender: string = 'M'; + private _isDisposed: boolean; + private _avatarEffectType: number = -1; + + public _Str_2153(k: string, _arg_2: string): void + { + this._data = new Map(); + this._colors = new Map(); + this._gender = _arg_2; + + this._Str_958(k); + } + + public dispose(): void + { + this._data = null; + this._colors = null; + this._isDisposed = true; + } + + public get disposed(): boolean + { + return this._isDisposed; + } + + private _Str_958(k: string): void + { + if(!k) return; + + for(const set of k.split('.')) + { + const _local_3 = set.split('-'); + + if(_local_3.length > 0) + { + const part = _local_3[0]; + const setId = parseInt(_local_3[1]); + const colors: number[] = []; + + let i = 2; + + while(i < _local_3.length) + { + colors.push(parseInt(_local_3[i])); + + i++; + } + + if(!colors.length) colors.push(0); + + this._Str_1876(part, setId, false); + this.savePartSetColourId(part, colors, false); + } + } + } + + public _Str_2131(k: string): boolean + { + return !!this._data.get(k); + } + + public getPartSetId(k: string): number + { + if(this._Str_2131(k)) return this._data.get(k); + + return -1; + } + + public getColourIds(k: string): number[] + { + if(this._colors.get(k)) return this._colors.get(k); + + return []; + } + + public _Str_1008(): string + { + let figure = ''; + + const sets: string[] = []; + + for(const [ key, value ] of this._data.entries()) + { + let set = ((key + '-') + value); + + const colors = this._colors.get(key); + + if(colors) for(const color of colors) set = (set + ('-' + color)); + + sets.push(set); + } + + let i = 0; + + while(i < sets.length) + { + figure = (figure + sets[i]); + + if(i < (sets.length - 1)) figure = (figure + '.'); + + i++; + } + + return figure; + } + + public _Str_2088(k: string, _arg_2: number, _arg_3: number[], _arg_4: boolean = false): void + { + this._Str_1876(k, _arg_2, _arg_4); + this.savePartSetColourId(k, _arg_3, _arg_4); + } + + private _Str_1876(k: string, _arg_2: number, _arg_3: boolean = true): void + { + switch(k) + { + case FigureDataContainer.HD: + case FigureDataContainer.HR: + case FigureDataContainer.HA: + case FigureDataContainer.HE: + case FigureDataContainer.EA: + case FigureDataContainer.FA: + case FigureDataContainer.CH: + case FigureDataContainer.CC: + case FigureDataContainer.CA: + case FigureDataContainer.CP: + case FigureDataContainer.LG: + case FigureDataContainer.SH: + case FigureDataContainer.WA: + if(_arg_2 >= 0) + { + this._data.set(k, _arg_2); + } + else + { + this._data.delete(k); + } + } + } + + public savePartSetColourId(k: string, _arg_2: number[], _arg_3: boolean = true): void + { + switch(k) + { + case FigureDataContainer.HD: + case FigureDataContainer.HR: + case FigureDataContainer.HA: + case FigureDataContainer.HE: + case FigureDataContainer.EA: + case FigureDataContainer.FA: + case FigureDataContainer.CH: + case FigureDataContainer.CC: + case FigureDataContainer.CA: + case FigureDataContainer.CP: + case FigureDataContainer.LG: + case FigureDataContainer.SH: + case FigureDataContainer.WA: + this._colors.set(k, _arg_2); + return; + } + } + + public getFigureStringWithFace(k: number): string + { + const partSets: string[] = [ FigureDataContainer.HD ]; + + let figure = ''; + const sets: string[] = []; + + for(const part of partSets) + { + const colors = this._colors.get(part); + + if(colors) + { + let setId = this._data.get(part); + + if(part === FigureDataContainer.HD) setId = k; + + let set = ((part + '-') + setId); + + if(setId >= 0) + { + let i = 0; + + while(i < colors.length) + { + set = (set + ('-' + colors[i])); + + i++; + } + } + + sets.push(set); + } + } + + let i = 0; + + while(i < sets.length) + { + figure = (figure + sets[i]); + + if(i < (sets.length - 1)) figure = (figure + '.'); + + i++; + } + + return figure; + } + + public get gender(): string + { + return this._gender; + } +} \ No newline at end of file diff --git a/src/nitro/utils/FixedSizeStack.ts b/src/nitro/utils/FixedSizeStack.ts new file mode 100644 index 00000000..034a5040 --- /dev/null +++ b/src/nitro/utils/FixedSizeStack.ts @@ -0,0 +1,65 @@ +export class FixedSizeStack +{ + private _data: number[]; + private _maxSize: number; + private _index: number; + + constructor(k: number) + { + this._data = []; + this._maxSize = k; + this._index = 0; + } + + public reset(): void + { + this._data = []; + this._index = 0; + } + + public _Str_22775(k: number): void + { + if(this._data.length < this._maxSize) + { + this._data.push(k); + } + else + { + this._data[this._index] = k; + } + + this._index = ((this._index + 1) % this._maxSize); + } + + public _Str_25797(): number + { + let k = Number.MIN_VALUE; + + let _local_2 = 0; + + while(_local_2 < this._maxSize) + { + if(this._data[_local_2] > k) k = this._data[_local_2]; + + _local_2++; + } + + return k; + } + + public _Str_26219(): number + { + let k = Number.MAX_VALUE; + + let _local_2 = 0; + + while(_local_2 < this._maxSize) + { + if(this._data[_local_2] < k) k = this._data[_local_2]; + + _local_2++; + } + + return k; + } +} \ No newline at end of file diff --git a/src/nitro/utils/FriendlyTime.ts b/src/nitro/utils/FriendlyTime.ts new file mode 100644 index 00000000..acee315a --- /dev/null +++ b/src/nitro/utils/FriendlyTime.ts @@ -0,0 +1,47 @@ +import { Nitro } from '../Nitro'; + +export class FriendlyTime +{ + private static MINUTE: number = 60; + private static HOUR: number = (60 * FriendlyTime.MINUTE); + private static DAY: number = (24 * FriendlyTime.HOUR); + private static WEEK: number = (7 * FriendlyTime.DAY); + private static MONTH: number = (30 * FriendlyTime.DAY); + private static YEAR: number = (365 * FriendlyTime.DAY); + + + public static format(seconds: number, key: string = '', threshold: number = 3): string + { + if(seconds > (threshold * FriendlyTime.YEAR)) return FriendlyTime.getLocalization(('friendlytime.years' + key), Math.round((seconds / FriendlyTime.YEAR))); + + if(seconds > (threshold * FriendlyTime.MONTH)) return FriendlyTime.getLocalization(('friendlytime.months' + key), Math.round((seconds / FriendlyTime.MONTH))); + + if(seconds > (threshold * FriendlyTime.DAY)) return FriendlyTime.getLocalization(('friendlytime.days' + key), Math.round((seconds / FriendlyTime.DAY))); + + if(seconds > (threshold * FriendlyTime.HOUR)) return FriendlyTime.getLocalization(('friendlytime.hours' + key), Math.round((seconds / FriendlyTime.HOUR))); + + if(seconds > (threshold * FriendlyTime.MINUTE)) return FriendlyTime.getLocalization(('friendlytime.minutes' + key), Math.round((seconds / FriendlyTime.MINUTE))); + + return FriendlyTime.getLocalization(('friendlytime.seconds' + key), Math.round(seconds)); + } + + public static shortFormat(seconds: number, key: string = '', threshold: number = 3): string + { + if(seconds > (threshold * FriendlyTime.YEAR)) return FriendlyTime.getLocalization(('friendlytime.years.short' + key), Math.round((seconds / FriendlyTime.YEAR))); + + if(seconds > (threshold * FriendlyTime.MONTH)) return FriendlyTime.getLocalization(('friendlytime.months.short' + key), Math.round((seconds / FriendlyTime.MONTH))); + + if(seconds > (threshold * FriendlyTime.DAY)) return FriendlyTime.getLocalization(('friendlytime.days.short' + key), Math.round((seconds / FriendlyTime.DAY))); + + if(seconds > (threshold * FriendlyTime.HOUR)) return FriendlyTime.getLocalization(('friendlytime.hours.short' + key), Math.round((seconds / FriendlyTime.HOUR))); + + if(seconds > (threshold * FriendlyTime.MINUTE)) return FriendlyTime.getLocalization(('friendlytime.minutes.short' + key), Math.round((seconds / FriendlyTime.MINUTE))); + + return FriendlyTime.getLocalization(('friendlytime.seconds.short' + key), Math.round(seconds)); + } + + public static getLocalization(key: string, amount: number): string + { + return Nitro.instance.getLocalizationWithParameter(key, 'amount', amount.toString()); + } +} diff --git a/src/nitro/utils/FurniId.ts b/src/nitro/utils/FurniId.ts new file mode 100644 index 00000000..92bad2b0 --- /dev/null +++ b/src/nitro/utils/FurniId.ts @@ -0,0 +1,9 @@ +export class FurniId +{ + private static BUILDER_CLUB_FURNI_ID_BASE: number = 0x7FFF0000; + + public static isBuilderClubId(k: number): boolean + { + return (k >= FurniId.BUILDER_CLUB_FURNI_ID_BASE); + } +} \ No newline at end of file diff --git a/src/nitro/utils/HabboWebTools.ts b/src/nitro/utils/HabboWebTools.ts new file mode 100644 index 00000000..2765f0f3 --- /dev/null +++ b/src/nitro/utils/HabboWebTools.ts @@ -0,0 +1,333 @@ +import { NitroLogger } from '../../core/common/logger/NitroLogger'; +import { LegacyExternalInterface } from '../externalInterface/LegacyExternalInterface'; + +export class HabboWebTools +{ + public static ADVERTISEMENT: string = 'advertisement'; + public static OPENLINK: string = 'openlink'; + public static OPENROOM: string = 'openroom'; + + public static logEventLog(data: string): void + { + try + { + if(LegacyExternalInterface.available) + { + LegacyExternalInterface.call('logEventLog', data); + } + } + + catch (e) + { + NitroLogger.log('External interface not working, failed to log event log.'); + } + } + + public static openPage(pageUrl: string): void + { + try + { + if(LegacyExternalInterface.available) + { + LegacyExternalInterface.call('openPage', pageUrl); + } + else + { + NitroLogger.log('External interface not available, openPage failed.'); + } + } + + catch (e) + { + NitroLogger.log(('Failed to open web page ' + pageUrl)); + } + } + + public static sendHeartBeat(): void + { + try + { + if(LegacyExternalInterface.available) + { + LegacyExternalInterface.call('heartBeat'); + } + } + + catch (e) + { + NitroLogger.log('Failed to send heartbeat'); + } + } + + public static openWebPageAndMinimizeClient(pageUrl: string): void + { + try + { + if(LegacyExternalInterface.available) + { + HabboWebTools.openPage(pageUrl); + } + } + + catch (e) + { + NitroLogger.log(('Failed to open web page ' + pageUrl)); + } + } + + public static closeWebPageAndRestoreClient(): void + { + try + { + if(LegacyExternalInterface.available) + { + LegacyExternalInterface.call('closeWebPageAndRestoreClient'); + } + } + + catch (e) + { + NitroLogger.log('Failed to close web page and restore client!'); + } + } + + public static openHabblet(name: string, param: string=null): void + { + try + { + if(LegacyExternalInterface.available) + { + LegacyExternalInterface.call('openHabblet', name, param); + } + } + + catch (e) + { + NitroLogger.log(('Failed to open Habblet ' + name)); + } + } + + public static closeHabblet(name: string, param: string=null): void + { + try + { + if(LegacyExternalInterface.available) + { + LegacyExternalInterface.call('closeHabblet', name, param); + } + } + + catch (e) + { + NitroLogger.log(('Failed to close Habblet ' + name)); + } + } + + public static send(reasonCode: number, reasonString: string): void + { + try + { + if(LegacyExternalInterface.available) + { + LegacyExternalInterface.call('disconnect', reasonCode, reasonString); + } + } + + catch (e) + { + NitroLogger.log('Failed to close send '); + } + } + + public static showGame(gameUrl: string): void + { + try + { + if(LegacyExternalInterface.available) + { + LegacyExternalInterface.callGame('showGame', gameUrl); + } + } + + catch (e) + { + NitroLogger.log(('Failed to open game: ' + e)); + } + } + + public static hideGame(): void + { + try + { + if(LegacyExternalInterface.available) + { + LegacyExternalInterface.callGame('hideGame'); + } + } + + catch (e) + { + NitroLogger.log('Failed to hide game'); + } + } + + public static open(url: string): void + { + try + { + if(LegacyExternalInterface.available) + { + LegacyExternalInterface.call('openExternalLink', escape(url)); + } + else + { + NitroLogger.log(('External interface not available. Could not request to open: ' + url)); + } + } + + catch (e) + { + NitroLogger.log(('External interface not working. Could not request to open: ' + url)); + } + } + + public static roomVisited(roomId: number): void + { + try + { + if(LegacyExternalInterface.available) + { + LegacyExternalInterface.call('roomVisited', roomId); + } + else + { + NitroLogger.log('External interface not available. Could not store last room visit.'); + } + } + + catch (e) + { + NitroLogger.log('External interface not working. Could not store last room visit.'); + } + } + + public static openMinimail(target: string): void + { + try + { + if(LegacyExternalInterface.available) + { + LegacyExternalInterface.call('openMinimail', target); + } + else + { + NitroLogger.log('External interface not available. Could not open minimail.'); + } + } + + catch (e) + { + NitroLogger.log('External interface not working. Could not open minimail.'); + } + } + + public static openNews(): void + { + try + { + if(LegacyExternalInterface.available) + { + LegacyExternalInterface.call('openNews'); + } + else + { + NitroLogger.log('External interface not available. Could not open news.'); + } + } + + catch (e) + { + NitroLogger.log('External interface not working. Could not open news.'); + } + } + + public static closeNews(): void + { + try + { + if(LegacyExternalInterface.available) + { + LegacyExternalInterface.call('closeNews'); + } + else + { + NitroLogger.log('External interface not available. Could not close news.'); + } + } + + catch (e) + { + NitroLogger.log('External interface not working. Could not close news.'); + } + } + + public static openAvatars(): void + { + try + { + if(LegacyExternalInterface.available) + { + LegacyExternalInterface.call('openAvatars'); + } + else + { + NitroLogger.log('External interface not available. Could not open avatars.'); + } + } + + catch (e) + { + NitroLogger.log('External interface not working. Could not open avatars.'); + } + } + + public static openRoomEnterAd(): void + { + try + { + if(LegacyExternalInterface.available) + { + LegacyExternalInterface.call('openRoomEnterAd'); + } + else + { + NitroLogger.log('External interface not available. Could not open roomenterad.'); + } + } + + catch (e) + { + NitroLogger.log('External interface not working. Could not open roomenterad.'); + } + } + + public static updateFigure(figure: string): void + { + try + { + if(LegacyExternalInterface.available) + { + LegacyExternalInterface.call('updateFigure', figure); + } + else + { + NitroLogger.log('External interface not available. Could not update figure.'); + } + } + + catch (e) + { + NitroLogger.log('External interface not working. Could not update figure.'); + } + } +} \ No newline at end of file diff --git a/src/nitro/utils/WebGL.ts b/src/nitro/utils/WebGL.ts new file mode 100644 index 00000000..3539fd4c --- /dev/null +++ b/src/nitro/utils/WebGL.ts @@ -0,0 +1,9 @@ +import { utils } from 'pixi.js'; + +export class WebGL +{ + public static isWebGLAvailable(): boolean + { + return utils.isWebGLSupported(); + } +} \ No newline at end of file diff --git a/src/nitro/window/motion/Callback.ts b/src/nitro/window/motion/Callback.ts new file mode 100644 index 00000000..259f13c3 --- /dev/null +++ b/src/nitro/window/motion/Callback.ts @@ -0,0 +1,30 @@ +import { Motion } from './Motion'; + +export class Callback extends Motion +{ + protected _callback: Function; + + constructor(k: Function) + { + super(null); + + this._callback = k; + } + + public get running(): boolean + { + return (this._running && !!this._callback); + } + + public tick(k: number): void + { + super.tick(k); + + if(this._callback) + { + this._callback(); + + this._callback = null; + } + } +} \ No newline at end of file diff --git a/src/nitro/window/motion/Combo.ts b/src/nitro/window/motion/Combo.ts new file mode 100644 index 00000000..a5450c68 --- /dev/null +++ b/src/nitro/window/motion/Combo.ts @@ -0,0 +1,61 @@ +import { Motion } from './Motion'; + +export class Combo extends Motion +{ + private _runningMotions: Motion[]; + private _removedMotions: Motion[]; + + constructor(...motions: Motion[]) + { + super((motions && motions.length) ? motions[0].target : null); + + this._runningMotions = []; + this._removedMotions = []; + + for(const motion of motions) this._runningMotions.push(motion); + } + + public start(): void + { + super.start(); + + for(const motion of this._runningMotions) motion.start(); + } + + public tick(k: number): void + { + super.tick(k); + + let motion: Motion = null; + + while(((motion = this._removedMotions.pop()) !== null)) + { + this._runningMotions.splice(this._removedMotions.indexOf(motion), 1); + + if(motion.running) motion.stop(); + } + + for(const motion of this._runningMotions) + { + if(motion.running) motion.tick(k); + + if(motion.complete) this._removedMotions.push(motion); + } + + if(this._runningMotions.length > 0) + { + for(const motion of this._runningMotions) + { + this._target = motion.target; + + if(this._target) break; + } + + this._complete = false; + } + else + { + this._complete = true; + } + } +} \ No newline at end of file diff --git a/src/nitro/window/motion/Dispose.ts b/src/nitro/window/motion/Dispose.ts new file mode 100644 index 00000000..252b8e35 --- /dev/null +++ b/src/nitro/window/motion/Dispose.ts @@ -0,0 +1,21 @@ +import { Motion } from './Motion'; + +export class Dispose extends Motion +{ + constructor(k: HTMLElement) + { + super(k); + } + + public tick(k: number): void + { + super.tick(k); + + if(this.target) + { + this.target.remove(); + + this.target = null; + } + } +} \ No newline at end of file diff --git a/src/nitro/window/motion/DropBounce.ts b/src/nitro/window/motion/DropBounce.ts new file mode 100644 index 00000000..7b52fceb --- /dev/null +++ b/src/nitro/window/motion/DropBounce.ts @@ -0,0 +1,60 @@ +import { Interval } from './Interval'; + +export class DropBounce extends Interval +{ + private _height: number; + private _offset: number; + + constructor(target: HTMLElement, duration: number, height: number) + { + super(target, duration); + + this._height = height; + } + + public start(): void + { + super.start(); + + this._offset = 0; + + this.target.style.top = ((this._offset - this._height) + 'px'); + } + + public update(time: number): void + { + super.update(time); + + this.target.style.top = (((this._offset - this._height) + (this.getBounceOffset(time) * this._height)) + 'px'); + } + + protected getBounceOffset(k: number): number + { + if(k < 0.364) return (7.5625 * k) * k; + + if(k < 0.727) + { + k = (k - 0.545); + + return ((7.5625 * k) * k) + 0.75; + } + + if(k < 0.909) + { + k = (k - 0.9091); + + return ((7.5625 * k) * k) + 0.9375; + } + + k = (k - 0.955); + + return ((7.5625 * k) * k) + 0.984375; + } + + public stop(): void + { + this.target.style.top = (this._offset + 'px'); + + super.stop(); + } +} \ No newline at end of file diff --git a/src/nitro/window/motion/Ease.ts b/src/nitro/window/motion/Ease.ts new file mode 100644 index 00000000..1034cdf6 --- /dev/null +++ b/src/nitro/window/motion/Ease.ts @@ -0,0 +1,34 @@ +import { Interval } from './Interval'; + +export class Ease extends Interval +{ + protected _interval: Interval; + + constructor(k: Interval) + { + super(k.target, k.duration); + + this._interval = k; + } + + public start(): void + { + super.start(); + + this._interval.start(); + } + + public update(k: number): void + { + super.update(k); + + this._interval.update(k); + } + + public stop(): void + { + super.stop(); + + this._interval.stop(); + } +} \ No newline at end of file diff --git a/src/nitro/window/motion/EaseOut.ts b/src/nitro/window/motion/EaseOut.ts new file mode 100644 index 00000000..5294b1d3 --- /dev/null +++ b/src/nitro/window/motion/EaseOut.ts @@ -0,0 +1,15 @@ +import { EaseRate } from './EaseRate'; +import { Interval } from './Interval'; + +export class EaseOut extends EaseRate +{ + constructor(k: Interval, _arg_2: number) + { + super(k, _arg_2); + } + + public update(k: number): void + { + this._interval.update(Math.pow(k, (1 / this._Str_21638))); + } +} \ No newline at end of file diff --git a/src/nitro/window/motion/EaseRate.ts b/src/nitro/window/motion/EaseRate.ts new file mode 100644 index 00000000..e7652064 --- /dev/null +++ b/src/nitro/window/motion/EaseRate.ts @@ -0,0 +1,14 @@ +import { Ease } from './Ease'; +import { Interval } from './Interval'; + +export class EaseRate extends Ease +{ + protected _Str_21638: number; + + constructor(k: Interval, _arg_2: number) + { + super(k); + + this._Str_21638 = _arg_2; + } +} \ No newline at end of file diff --git a/src/nitro/window/motion/Interval.ts b/src/nitro/window/motion/Interval.ts new file mode 100644 index 00000000..1afb7231 --- /dev/null +++ b/src/nitro/window/motion/Interval.ts @@ -0,0 +1,47 @@ +import { Nitro } from '../../Nitro'; +import { Motion } from './Motion'; + +export class Interval extends Motion +{ + private _startTimeMs: number; + private _duration: number; + + constructor(target: HTMLElement, duration: number) + { + super(target); + + this._complete = false; + this._duration = duration; + } + + public get duration(): number + { + return this._duration; + } + + public start(): void + { + super.start(); + + this._complete = false; + this._startTimeMs = Nitro.instance.time; + } + + public tick(time: number): void + { + super.tick(time); + + const elapsed = ((time - this._startTimeMs) / this._duration); + + if(elapsed < 1) + { + this.update(elapsed); + } + else + { + this.update(1); + + this._complete = true; + } + } +} diff --git a/src/nitro/window/motion/JumpBy.ts b/src/nitro/window/motion/JumpBy.ts new file mode 100644 index 00000000..a5cd8a7f --- /dev/null +++ b/src/nitro/window/motion/JumpBy.ts @@ -0,0 +1,37 @@ +import { Interval } from './Interval'; + +export class JumpBy extends Interval +{ + protected _startX: number; + protected _startY: number; + protected _deltaX: number; + protected _deltaY: number; + protected _height: number; + protected _numJumps: number; + + constructor(target: HTMLElement, duration: number, deltaX: number, deltaY: number, height: number, numJumps: number) + { + super(target, duration); + + this._deltaX = deltaX; + this._deltaY = deltaY; + this._height = -(height); + this._numJumps = numJumps; + } + + public start(): void + { + super.start(); + + this._startX = this.target.offsetLeft; + this._startY = this.target.offsetTop; + } + + public update(k: number): void + { + super.update(k); + + this.target.style.left = ((this._startX + (this._deltaX * k)) + 'px'); + this.target.style.top = (((this._startY + (this._height * Math.abs(Math.sin(((k * Math.PI) * this._numJumps))))) + (this._deltaY * k)) + 'px'); + } +} \ No newline at end of file diff --git a/src/nitro/window/motion/Motion.ts b/src/nitro/window/motion/Motion.ts new file mode 100644 index 00000000..acf6f58f --- /dev/null +++ b/src/nitro/window/motion/Motion.ts @@ -0,0 +1,61 @@ +export class Motion +{ + protected _target: HTMLElement; + protected _running: boolean; + protected _complete: boolean = true; + protected _tag: string; + + constructor(target: HTMLElement) + { + this._target = target; + } + + public get running(): boolean + { + return ((this._running) && (!!this._target)); + } + + public get complete(): boolean + { + return this._complete; + } + + public set target(k: HTMLElement) + { + this._target = k; + } + + public get target(): HTMLElement + { + return this._target; + } + + public set tag(k: string) + { + this._tag = k; + } + + public get tag(): string + { + return this._tag; + } + + public start(): void + { + this._running = true; + } + + public update(k: number): void + { + } + + public stop(): void + { + this._target = null; + this._running = false; + } + + public tick(k: number): void + { + } +} \ No newline at end of file diff --git a/src/nitro/window/motion/Motions.ts b/src/nitro/window/motion/Motions.ts new file mode 100644 index 00000000..7514076c --- /dev/null +++ b/src/nitro/window/motion/Motions.ts @@ -0,0 +1,193 @@ +import { Nitro } from '../../Nitro'; +import { Motion } from './Motion'; + +export class Motions +{ + private static _Str_5358: Motion[] = []; + private static _Str_3932: Motion[] = []; + private static _Str_10731: Motion[] = []; + private static _Str_5307: ReturnType = null; + private static _Str_7507: boolean = false; + + public static get TIMER_TIME(): number + { + return (1000 / Nitro.instance.ticker.FPS); + } + + public static _Str_4598(k: Motion): Motion + { + if(((Motions._Str_3932.indexOf(k) === -1) && (Motions._Str_5358.indexOf(k) === -1))) + { + if(Motions._Str_7507) + { + Motions._Str_5358.push(k); + } + else + { + Motions._Str_3932.push(k); + + k.start(); + } + + Motions._Str_12757(); + } + + return k; + } + + public static _Str_15790(k:Motion): void + { + let _local_2: number = Motions._Str_3932.indexOf(k); + + if(_local_2 > -1) + { + if(Motions._Str_7507) + { + _local_2 = Motions._Str_10731.indexOf(k); + + if(_local_2 == -1) Motions._Str_10731.push(k); + } + else + { + Motions._Str_3932.splice(_local_2, 1); + + if(k.running) k.stop(); + + if(!Motions._Str_3932.length) Motions._Str_7465(); + } + } + else + { + _local_2 = Motions._Str_5358.indexOf(k); + + if(_local_2 > -1) Motions._Str_5358.splice(_local_2, 1); + } + } + + public static _Str_19320(k: string):Motion + { + for(const _local_2 of Motions._Str_3932) + { + if(_local_2.tag == k) return _local_2; + } + + for(const _local_2 of Motions._Str_5358) + { + if(_local_2.tag == k) return _local_2; + } + + return null; + } + + public static _Str_9810(k: HTMLElement):Motion + { + for(const _local_2 of Motions._Str_3932) + { + if(_local_2.target == k) return _local_2; + } + + for(const _local_2 of Motions._Str_5358) + { + if(_local_2.target == k) return _local_2; + } + + return null; + } + + public static _Str_26365(k: string, _arg_2: HTMLElement):Motion + { + for(const _local_3 of Motions._Str_3932) + { + if(((_local_3.tag == k) && (_local_3.target == _arg_2))) return _local_3; + } + + for(const _local_3 of Motions._Str_5358) + { + if(((_local_3.tag == k) && (_local_3.target == _arg_2))) return _local_3; + } + + return null; + } + + public static get _Str_1349(): boolean + { + return !!Motions._Str_5307; + } + + public static get _Str_26314(): boolean + { + return Motions._Str_7507; + } + + private static _Str_21055(): void + { + Motions._Str_7507 = true; + + const _local_2: number = Nitro.instance.time; + + let _local_3: Motion = null; + + // eslint-disable-next-line no-cond-assign + while(_local_3 = Motions._Str_5358.pop()) Motions._Str_3932.push(_local_3); + + // eslint-disable-next-line no-cond-assign + while(_local_3 = Motions._Str_10731.pop()) + { + Motions._Str_3932.splice(Motions._Str_3932.indexOf(_local_3), 1); + + if(_local_3.running) _local_3.stop(); + } + + for(_local_3 of Motions._Str_3932) + { + if(_local_3.running) + { + _local_3.tick(_local_2); + + if(_local_3.complete) + { + Motions._Str_15790(_local_3); + } + } + else + { + Motions._Str_15790(_local_3); + } + } + + if(!Motions._Str_3932.length) Motions._Str_7465(); + + Motions._Str_7507 = false; + } + + private static _Str_12757(): void + { + if(!Motions._Str_5307) + { + Motions._Str_5307 = setInterval(Motions._Str_21055, Motions.TIMER_TIME); + } + } + + private static _Str_7465(): void + { + if(Motions._Str_5307) + { + clearInterval(Motions._Str_5307); + + Motions._Str_5307 = null; + } + } + + + public _Str_25883(k: HTMLElement): number + { + let _local_2 = 0; + + for(const _local_3 of Motions._Str_3932) + { + if(_local_3.target === k) _local_2++; + } + + return _local_2; + } +} diff --git a/src/nitro/window/motion/MoveBy.ts b/src/nitro/window/motion/MoveBy.ts new file mode 100644 index 00000000..16399014 --- /dev/null +++ b/src/nitro/window/motion/MoveBy.ts @@ -0,0 +1,17 @@ +import { MoveTo } from './MoveTo'; + +export class MoveBy extends MoveTo +{ + constructor(k: HTMLElement, _arg_2: number, _arg_3: number, _arg_4: number) + { + super(k, _arg_2, _arg_3, _arg_4); + } + + public start(): void + { + this._endX = (this.target.offsetLeft + this._endX); + this._endY = (this.target.offsetTop + this._endY); + + super.start(); + } +} \ No newline at end of file diff --git a/src/nitro/window/motion/MoveTo.ts b/src/nitro/window/motion/MoveTo.ts new file mode 100644 index 00000000..0c936196 --- /dev/null +++ b/src/nitro/window/motion/MoveTo.ts @@ -0,0 +1,35 @@ +import { Interval } from './Interval'; + +export class MoveTo extends Interval +{ + protected _startX: number; + protected _startY: number; + protected _endX: number; + protected _endY: number; + protected _deltaX: number; + protected _deltaY: number; + + constructor(k: HTMLElement, _arg_2: number, _arg_3: number, _arg_4: number) + { + super(k, _arg_2); + + this._endX = _arg_3; + this._endY = _arg_4; + } + + public start(): void + { + super.start(); + + this._startX = this.target.offsetLeft; + this._startY = this.target.offsetTop; + this._deltaX = (this._endX - this._startX); + this._deltaY = (this._endY - this._startY); + } + + public update(k: number): void + { + this.target.style.left = ((this._startX + (this._deltaX * k)) + 'px'); + this.target.style.top = ((this._startY + (this._deltaY * k)) + 'px'); + } +} \ No newline at end of file diff --git a/src/nitro/window/motion/Queue.ts b/src/nitro/window/motion/Queue.ts new file mode 100644 index 00000000..e63baf47 --- /dev/null +++ b/src/nitro/window/motion/Queue.ts @@ -0,0 +1,71 @@ +import { Motion } from './Motion'; + +export class Queue extends Motion +{ + private _motion: Motion; + private _queue: Motion[]; + + constructor(...motions: Motion[]) + { + super((motions ? motions[0].target : null)); + + this._queue = []; + + for(const motion of motions) this._queue.push(motion); + + this._motion = motions[0]; + this._complete = !this._motion; + } + + public get running(): boolean + { + return ((this._running && this._motion) ? this._motion.running : false); + } + + public start(): void + { + super.start(); + + this._motion.start(); + } + + public update(k: number): void + { + super.update(k); + + if(this._motion.running) this._motion.update(k); + } + + public stop(): void + { + super.stop(); + + this._motion.stop(); + } + + public tick(k: number): void + { + super.tick(k); + + this._motion.tick(k); + + if(this._motion.complete) + { + this._motion.stop(); + + const index = this._queue.indexOf(this._motion); + + if(index < (this._queue.length - 1)) + { + this._motion = this._queue[(index + 1)]; + this._target = this._motion.target; + + this._motion.start(); + } + else + { + this._complete = true; + } + } + } +} \ No newline at end of file diff --git a/src/nitro/window/motion/ResizeTo.ts b/src/nitro/window/motion/ResizeTo.ts new file mode 100644 index 00000000..62a5563d --- /dev/null +++ b/src/nitro/window/motion/ResizeTo.ts @@ -0,0 +1,35 @@ +import { Interval } from './Interval'; + +export class ResizeTo extends Interval +{ + protected _startW: number; + protected _startH: number; + protected _endW: number; + protected _endH: number; + protected _deltaW: number; + protected _deltaH: number; + + constructor(k: HTMLElement, _arg_2: number, _arg_3: number, _arg_4: number) + { + super(k, _arg_2); + + this._endW = _arg_3; + this._endH = _arg_4; + } + + public start(): void + { + super.start(); + + this._startW = this.target.offsetWidth; + this._startH = this.target.offsetHeight; + this._deltaW = (this._endW - this._startW); + this._deltaH = (this._endH - this._startH); + } + + public update(k: number): void + { + this.target.style.width = ((this._startW + (this._deltaW * k)) + 'px'); + this.target.style.height = ((this._startH + (this._deltaH * k)) + 'px'); + } +} \ No newline at end of file diff --git a/src/nitro/window/motion/Wait.ts b/src/nitro/window/motion/Wait.ts new file mode 100644 index 00000000..e51c06eb --- /dev/null +++ b/src/nitro/window/motion/Wait.ts @@ -0,0 +1,37 @@ +import { Nitro } from '../../Nitro'; +import { Motion } from './Motion'; + +export class Wait extends Motion +{ + private _startTimeMs: number; + private _waitTimeMs: number; + + constructor(k: number) + { + super(null); + + this._waitTimeMs = k; + } + + public get running(): boolean + { + return this._running; + } + + public start(): void + { + super.start(); + + this._complete = false; + this._startTimeMs = Nitro.instance.time; + } + + public tick(k: number): void + { + super.tick(k); + + this._complete = ((k - this._startTimeMs) >= this._waitTimeMs); + + if(this._complete) this.stop(); + } +} diff --git a/src/room/IRoomInstance.ts b/src/room/IRoomInstance.ts new file mode 100644 index 00000000..d22f420f --- /dev/null +++ b/src/room/IRoomInstance.ts @@ -0,0 +1,28 @@ +import { IDisposable } from '../core/common/disposable/IDisposable'; +import { IRoomInstanceContainer } from './IRoomInstanceContainer'; +import { IRoomObjectManager } from './IRoomObjectManager'; +import { IRoomObject } from './object/IRoomObject'; +import { IRoomObjectModel } from './object/IRoomObjectModel'; +import { IRoomRendererBase } from './renderer/IRoomRendererBase'; + +export interface IRoomInstance extends IDisposable +{ + setRenderer(renderer: IRoomRendererBase): void; + getManager(category: number): IRoomObjectManager; + getTotalObjectsForManager(category: number): number; + getRoomObject(id: number, category: number): IRoomObject; + getRoomObjectsForCategory(category: number): IRoomObject[]; + getRoomObjectByIndex(index: number, category: number): IRoomObject; + createRoomObject(id: number, stateCount: number, type: string, category: number): IRoomObject; + createRoomObjectAndInitalize(objectId: number, type: string, category: number): IRoomObject; + removeRoomObject(id: number, category: number): void; + removeAllManagers(): void; + addUpdateCategory(category: number): void; + removeUpdateCategory(category: number): void; + update(time: number, update?: boolean): void; + id: string; + container: IRoomInstanceContainer; + renderer: IRoomRendererBase; + managers: Map; + model: IRoomObjectModel; +} \ No newline at end of file diff --git a/src/room/IRoomInstanceContainer.ts b/src/room/IRoomInstanceContainer.ts new file mode 100644 index 00000000..02233653 --- /dev/null +++ b/src/room/IRoomInstanceContainer.ts @@ -0,0 +1,8 @@ +import { IRoomObjectManager } from './IRoomObjectManager'; +import { IRoomObject } from './object/IRoomObject'; + +export interface IRoomInstanceContainer +{ + createRoomObjectAndInitalize(roomId: string, objectId: number, type: string, category: number): IRoomObject; + createRoomObjectManager(category: number): IRoomObjectManager; +} \ No newline at end of file diff --git a/src/room/IRoomManager.ts b/src/room/IRoomManager.ts new file mode 100644 index 00000000..a3e06e56 --- /dev/null +++ b/src/room/IRoomManager.ts @@ -0,0 +1,19 @@ +import { INitroManager } from '../core/common/INitroManager'; +import { IEventDispatcher } from '../core/events/IEventDispatcher'; +import { RoomContentLoader } from '../nitro/room/RoomContentLoader'; +import { IRoomInstance } from './IRoomInstance'; +import { IRoomObject } from './object/IRoomObject'; + +export interface IRoomManager extends INitroManager +{ + getRoomInstance(roomId: string): IRoomInstance; + createRoomInstance(roomId: string): IRoomInstance; + removeRoomInstance(roomId: string): boolean; + addUpdateCategory(category: number): void; + removeUpdateCategory(category: number): void; + createRoomObjectAndInitalize(roomId: string, objectId: number, type: string, category: number): IRoomObject; + setContentLoader(loader: RoomContentLoader): void; + update(time: number, update?: boolean): void; + rooms: Map; + events: IEventDispatcher; +} \ No newline at end of file diff --git a/src/room/IRoomManagerListener.ts b/src/room/IRoomManagerListener.ts new file mode 100644 index 00000000..3bf9681b --- /dev/null +++ b/src/room/IRoomManagerListener.ts @@ -0,0 +1,6 @@ +export interface IRoomManagerListener +{ + onRoomEngineInitalized(flag: boolean): void; + objectInitialized(roomId: string, objectId: number, category: number): void; + initalizeTemporaryObjectsByType(type: string, _arg_2: boolean): void; +} \ No newline at end of file diff --git a/src/room/IRoomObjectManager.ts b/src/room/IRoomObjectManager.ts new file mode 100644 index 00000000..a0b1de08 --- /dev/null +++ b/src/room/IRoomObjectManager.ts @@ -0,0 +1,14 @@ +import { AdvancedMap } from '../core/utils/AdvancedMap'; +import { IRoomObjectController } from './object/IRoomObjectController'; + +export interface IRoomObjectManager +{ + dispose(): void; + getObject(id: number): IRoomObjectController; + getObjectByIndex(index: number): IRoomObjectController; + createObject(id: number, stateCount: number, type: string): IRoomObjectController; + removeObject(id: number): void; + removeAllObjects(): void; + objects: AdvancedMap; + totalObjects: number; +} \ No newline at end of file diff --git a/src/room/RoomInstance.ts b/src/room/RoomInstance.ts new file mode 100644 index 00000000..c54129b4 --- /dev/null +++ b/src/room/RoomInstance.ts @@ -0,0 +1,300 @@ +import { Disposable } from '../core/common/disposable/Disposable'; +import { IRoomInstance } from './IRoomInstance'; +import { IRoomInstanceContainer } from './IRoomInstanceContainer'; +import { IRoomObjectManager } from './IRoomObjectManager'; +import { IRoomObject } from './object/IRoomObject'; +import { IRoomObjectController } from './object/IRoomObjectController'; +import { IRoomObjectModel } from './object/IRoomObjectModel'; +import { RoomObjectModel } from './object/RoomObjectModel'; +import { IRoomRendererBase } from './renderer/IRoomRendererBase'; + +export class RoomInstance extends Disposable implements IRoomInstance +{ + private _id: string; + private _container: IRoomInstanceContainer; + private _renderer: IRoomRendererBase; + private _managers: Map; + private _updateCategories: number[]; + private _model: IRoomObjectModel; + + constructor(id: string, container: IRoomInstanceContainer) + { + super(); + + this._id = id; + this._container = container; + this._renderer = null; + this._managers = new Map(); + this._updateCategories = []; + this._model = new RoomObjectModel(); + } + + protected onDispose(): void + { + this.removeAllManagers(); + + this.destroyRenderer(); + + this._container = null; + + this._model.dispose(); + } + + public setRenderer(renderer: IRoomRendererBase): void + { + if(renderer === this._renderer) return; + + if(this._renderer) this.destroyRenderer(); + + this._renderer = renderer; + + if(!this._renderer) return; + + this._renderer.reset(); + + if(this._managers.size) + { + for(const manager of this._managers.values()) + { + if(!manager) continue; + + const objects = manager.objects; + + if(!objects.length) continue; + + for(const object of objects.getValues()) + { + if(!object) continue; + + this._renderer.addObject(object); + } + } + } + } + + private destroyRenderer(): void + { + if(!this._renderer) return; + + this._renderer.dispose(); + + this._renderer = null; + } + + public getManager(category: number): IRoomObjectManager + { + const manager = this._managers.get(category); + + if(!manager) return null; + + return manager; + } + + private getManagerOrCreate(category: number): IRoomObjectManager + { + let manager = this.getManager(category); + + if(manager) return manager; + + manager = this._container.createRoomObjectManager(category); + + if(!manager) return null; + + this._managers.set(category, manager); + + return manager; + } + + public getTotalObjectsForManager(category: number): number + { + const manager = this.getManager(category); + + if(!manager) return 0; + + return manager.totalObjects; + } + + public getRoomObject(id: number, category: number): IRoomObject + { + const manager = this.getManager(category); + + if(!manager) return null; + + const object = manager.getObject(id); + + if(!object) return null; + + return object; + } + + public getRoomObjectsForCategory(category: number): IRoomObject[] + { + const manager = this.getManager(category); + + return (manager ? manager.objects.getValues() : []); + } + + public getRoomObjectByIndex(index: number, category: number): IRoomObject + { + const manager = this.getManager(category); + + if(!manager) return null; + + const object = manager.getObjectByIndex(index); + + if(!object) return null; + + return object; + } + + public createRoomObject(id: number, stateCount: number, type: string, category: number): IRoomObjectController + { + const manager = this.getManagerOrCreate(category); + + if(!manager) return null; + + const object = manager.createObject(id, stateCount, type); + + if(!object) return null; + + if(this._renderer) this._renderer.addObject(object); + + return object; + } + + public createRoomObjectAndInitalize(objectId: number, type: string, category: number): IRoomObject + { + if(!this._container) return null; + + return this._container.createRoomObjectAndInitalize(this._id, objectId, type, category); + } + + public removeRoomObject(id: number, category: number): void + { + const manager = this.getManager(category); + + if(!manager) return; + + const object = manager.getObject(id); + + if(!object) return; + + object.tearDown(); + + if(this._renderer) this._renderer.removeObject(object); + + manager.removeObject(id); + } + + public removeAllManagers(): void + { + for(const manager of this._managers.values()) + { + if(!manager) continue; + + if(this._renderer) + { + const objects = manager.objects; + + if(objects.length) + { + for(const object of objects.getValues()) + { + if(!object) continue; + + this._renderer.removeObject(object); + } + } + } + + manager.dispose(); + } + + this._managers.clear(); + } + + public addUpdateCategory(category: number): void + { + const index = this._updateCategories.indexOf(category); + + if(index >= 0) return; + + this._updateCategories.push(category); + } + + public removeUpdateCategory(category: number): void + { + const index = this._updateCategories.indexOf(category); + + if(index === -1) return; + + this._updateCategories.splice(index, 1); + } + + public update(time: number, update: boolean = false): void + { + for(const category of this._updateCategories) + { + const manager = this.getManager(category); + + if(!manager) continue; + + const objects = manager.objects; + + if(!objects.length) continue; + + for(const object of objects.getValues()) + { + if(!object) continue; + + const logic = object.logic; + + (logic && logic.update(time)); + } + } + + this._renderer && this._renderer.update(time, update); + } + + public hasUninitializedObjects(): boolean + { + for(const manager of this._managers.values()) + { + if(!manager) continue; + + for(const object of manager.objects.getValues()) + { + if(!object) continue; + + if(!object.isReady) return true; + } + } + + return false; + } + + public get id(): string + { + return this._id; + } + + public get container(): IRoomInstanceContainer + { + return this._container; + } + + public get renderer(): IRoomRendererBase + { + return this._renderer; + } + + public get managers(): Map + { + return this._managers; + } + + public get model(): IRoomObjectModel + { + return this._model; + } +} \ No newline at end of file diff --git a/src/room/RoomManager.ts b/src/room/RoomManager.ts new file mode 100644 index 00000000..65449995 --- /dev/null +++ b/src/room/RoomManager.ts @@ -0,0 +1,412 @@ +import { NitroManager } from '../core/common/NitroManager'; +import { RoomContentLoader } from '../nitro/room/RoomContentLoader'; +import { RoomContentLoadedEvent } from './events/RoomContentLoadedEvent'; +import { IRoomInstance } from './IRoomInstance'; +import { IRoomInstanceContainer } from './IRoomInstanceContainer'; +import { IRoomManager } from './IRoomManager'; +import { IRoomManagerListener } from './IRoomManagerListener'; +import { IRoomObjectManager } from './IRoomObjectManager'; +import { IRoomObject } from './object/IRoomObject'; +import { IRoomObjectController } from './object/IRoomObjectController'; +import { IRoomObjectLogicFactory } from './object/logic/IRoomObjectLogicFactory'; +import { IRoomObjectVisualizationFactory } from './object/visualization/IRoomObjectVisualizationFactory'; +import { IGraphicAssetCollection } from './object/visualization/utils/IGraphicAssetCollection'; +import { RoomInstance } from './RoomInstance'; +import { RoomObjectManager } from './RoomObjectManager'; + +export class RoomManager extends NitroManager implements IRoomManager, IRoomInstanceContainer +{ + public static _Str_9994: number = -1; + public static _Str_16337: number = 0; + public static _Str_16443: number = 1; + public static _Str_13904: number = 2; + public static _Str_9846: number = 3; + private static _Str_18280: number = 40; + + private _state: number; + private _rooms: Map; + private _contentLoader: RoomContentLoader; + private _updateCategories: number[]; + + private _listener: IRoomManagerListener; + private _visualizationFactory: IRoomObjectVisualizationFactory; + private _logicFactory: IRoomObjectLogicFactory; + + private _initialLoadList: string[]; + private _pendingContentTypes: string[]; + private _skipContentProcessing: boolean; + + private _disposed: boolean; + + constructor(listener: IRoomManagerListener, visualizationFactory: IRoomObjectVisualizationFactory, logicFactory: IRoomObjectLogicFactory) + { + super(); + + this._state = RoomManager._Str_16443; + this._rooms = new Map(); + this._contentLoader = null; + this._updateCategories = []; + + this._listener = listener; + this._visualizationFactory = visualizationFactory; + this._logicFactory = logicFactory; + + this._initialLoadList = []; + this._pendingContentTypes = []; + this._skipContentProcessing = false; + + this._disposed = false; + + this.onRoomContentLoadedEvent = this.onRoomContentLoadedEvent.bind(this); + + this.events.addEventListener(RoomContentLoadedEvent.RCLE_SUCCESS, this.onRoomContentLoadedEvent); + this.events.addEventListener(RoomContentLoadedEvent.RCLE_FAILURE, this.onRoomContentLoadedEvent); + this.events.addEventListener(RoomContentLoadedEvent.RCLE_CANCEL, this.onRoomContentLoadedEvent); + } + + public onInit(): void + { + if(this._state >= RoomManager._Str_13904 || !this._contentLoader) return; + + const mandatoryLibraries = RoomContentLoader.MANDATORY_LIBRARIES; + + for(const library of mandatoryLibraries) + { + if(!library) continue; + + if(this._initialLoadList.indexOf(library) === -1) + { + this._contentLoader.downloadAsset(library, this.events); + + this._initialLoadList.push(library); + } + } + + this._state = RoomManager._Str_13904; + } + + public getRoomInstance(roomId: string): IRoomInstance + { + const existing = this._rooms.get(roomId); + + if(!existing) return null; + + return existing; + } + + public createRoomInstance(roomId: string): IRoomInstance + { + if(this._rooms.get(roomId)) return null; + + const instance = new RoomInstance(roomId, this); + + this._rooms.set(instance.id, instance); + + if(this._updateCategories.length) + { + for(const category of this._updateCategories) + { + instance.addUpdateCategory(category); + } + } + + return instance; + } + + public removeRoomInstance(roomId: string): boolean + { + const existing = this._rooms.get(roomId); + + if(!existing) return false; + + this._rooms.delete(roomId); + + existing.dispose(); + + return true; + } + + public createRoomObjectAndInitalize(roomId: string, objectId: number, type: string, category: number): IRoomObject + { + const instance = this.getRoomInstance(roomId); + + if(!instance) return null; + + let visualization = type; + let logic = type; + let assetName = type; + let asset: IGraphicAssetCollection = null; + let isLoading = false; + + if(this._contentLoader.isLoaderType(type)) + { + asset = this._contentLoader.getCollection(type); + + if(!asset) + { + isLoading = true; + + this._contentLoader.downloadAsset(type, this.events); + + assetName = this._contentLoader.getPlaceholderName(type); + asset = this._contentLoader.getCollection(assetName); + + if(!asset) return null; + } + + visualization = asset.data.visualizationType; + logic = asset.data.logicType; + } + + const object = (instance.createRoomObject(objectId, 1, type, category) as IRoomObjectController); + + if(!object) return null; + + if(this._visualizationFactory) + { + const visualizationInstance = this._visualizationFactory.getVisualization(visualization); + + if(!visualizationInstance) + { + instance.removeRoomObject(objectId, category); + + return null; + } + + visualizationInstance.asset = asset; + + const visualizationData = this._visualizationFactory.getVisualizationData(assetName, visualization, ((asset && asset.data) || null)); + + if(!visualizationData || !visualizationInstance.initialize(visualizationData)) + { + instance.removeRoomObject(objectId, category); + + return null; + } + + object.setVisualization(visualizationInstance); + } + + if(this._logicFactory) + { + const logicInstance = this._logicFactory.getLogic(logic); + + object.setLogic(logicInstance); + + if(logicInstance) + { + logicInstance.initialize((asset && asset.data) || null); + } + } + + if(!isLoading) object.isReady = true; + + this._contentLoader.setRoomObjectRoomId(object, roomId); + + return object; + } + + private reinitializeRoomObjectsByType(type: string): void + { + if(!type || !this._contentLoader || !this._visualizationFactory || !this._logicFactory) return; + + const asset = this._contentLoader.getCollection(type); + + if(!asset) return; + + const visualization = asset.data.visualizationType; + const logic = asset.data.logicType; + const visualizationData = this._visualizationFactory.getVisualizationData(type, visualization, asset.data); + + for(const room of this._rooms.values()) + { + if(!room) continue; + + for(const [ category, manager ] of room.managers.entries()) + { + if(!manager) continue; + + for(const object of manager.objects.getValues()) + { + if(!object || object.type !== type) continue; + + const visualizationInstance = this._visualizationFactory.getVisualization(visualization); + + if(visualizationInstance) + { + visualizationInstance.asset = asset; + + if(!visualizationData || !visualizationInstance.initialize(visualizationData)) + { + manager.removeObject(object.id); + } + else + { + object.setVisualization(visualizationInstance); + + const logicInstance = this._logicFactory.getLogic(logic); + + object.setLogic(logicInstance); + + if(logicInstance) + { + logicInstance.initialize(asset.data); + } + + object.isReady = true; + + if(this._listener) this._listener.objectInitialized(room.id, object.id, category); + } + } + else + { + manager.removeObject(object.id); + } + } + } + } + } + + public addUpdateCategory(category: number): void + { + const index = this._updateCategories.indexOf(category); + + if(index >= 0) return; + + this._updateCategories.push(category); + + if(!this._rooms.size) return; + + for(const room of this._rooms.values()) + { + if(!room) continue; + + room.addUpdateCategory(category); + } + } + + public removeUpdateCategory(category: number): void + { + const index = this._updateCategories.indexOf(category); + + if(index === -1) return; + + this._updateCategories.splice(index, 1); + + if(!this._rooms.size) return; + + for(const room of this._rooms.values()) + { + if(!room) continue; + + room.removeUpdateCategory(category); + } + } + + public setContentLoader(loader: RoomContentLoader): void + { + if(this._contentLoader) this._contentLoader.dispose(); + + this._contentLoader = loader; + } + + private processPendingContentTypes(time: number): void + { + if(this._skipContentProcessing) + { + this._skipContentProcessing = false; + + return; + } + + while(this._pendingContentTypes.length) + { + const type = this._pendingContentTypes.shift(); + + const collection = this._contentLoader.getCollection(type); + + if(!collection) + { + if(this._listener) + { + this._listener.initalizeTemporaryObjectsByType(type, false); + } + + this.logger.log(`Invalid Collection: ${ type }`); + + continue; + } + + this.reinitializeRoomObjectsByType(type); + + if(this._listener) this._listener.initalizeTemporaryObjectsByType(type, true); + + if(this._initialLoadList.length > 0) this.removeFromInitialLoad(type); + } + } + + private removeFromInitialLoad(type: string): void + { + if(!type || this._state === RoomManager._Str_9994) return; + + if(!this._contentLoader) this._state = RoomManager._Str_9994; + + if(this._contentLoader.getCollection(type)) + { + const i = this._initialLoadList.indexOf(type); + + if(i >= 0) this._initialLoadList.splice(i, 1); + + if(!this._initialLoadList.length) + { + this._state = RoomManager._Str_9846; + + if(this._listener) + { + this._listener.onRoomEngineInitalized(true); + } + } + } + else + { + this._state = RoomManager._Str_9994; + + if(this._listener) this._listener.onRoomEngineInitalized(false); + } + } + + private onRoomContentLoadedEvent(event: RoomContentLoadedEvent): void + { + if(!this._contentLoader) return; + + const contentType = event.contentType; + + if(this._pendingContentTypes.indexOf(contentType) >= 0) return; + + this._pendingContentTypes.push(contentType); + } + + public update(time: number, update: boolean = false): void + { + this.processPendingContentTypes(time); + + if(!this._rooms.size) return; + + for(const room of this._rooms.values()) room && room.update(time, update); + } + + public createRoomObjectManager(category: number): IRoomObjectManager + { + return new RoomObjectManager(); + } + + public get rooms(): Map + { + return this._rooms; + } + + public get disposed(): boolean + { + return this._disposed; + } +} \ No newline at end of file diff --git a/src/room/RoomObjectManager.ts b/src/room/RoomObjectManager.ts new file mode 100644 index 00000000..5d345248 --- /dev/null +++ b/src/room/RoomObjectManager.ts @@ -0,0 +1,131 @@ +import { AdvancedMap } from '../core/utils/AdvancedMap'; +import { IRoomObjectManager } from './IRoomObjectManager'; +import { IRoomObjectController } from './object/IRoomObjectController'; +import { RoomObject } from './object/RoomObject'; + +export class RoomObjectManager implements IRoomObjectManager +{ + private _objects: AdvancedMap; + private _objectsPerType: AdvancedMap>; + + constructor() + { + this._objects = new AdvancedMap(); + this._objectsPerType = new AdvancedMap(); + } + + public dispose(): void + { + this.removeAllObjects(); + } + + public getObject(id: number): IRoomObjectController + { + const object = this._objects.getValue(id); + + if(!object) return null; + + return object; + } + + public getObjectByIndex(index: number): IRoomObjectController + { + const object = this._objects.getWithIndex(index); + + if(!object) return null; + + return object; + } + + public createObject(id: number, stateCount: number, type: string): IRoomObjectController + { + const object = new RoomObject(id, stateCount, type); + + return this.addObject(id, type, object); + } + + private addObject(id: number, type: string, object: IRoomObjectController): IRoomObjectController + { + if(this._objects.getValue(id)) + { + object.dispose(); + + return null; + } + + this._objects.add(id, object); + + const typeMap = this.getTypeMap(type); + + if(typeMap) typeMap.add(id, object); + + return object; + } + + public removeObject(id: number): void + { + const object = this._objects.remove(id); + + if(object) + { + const typeMap = this.getTypeMap(object.type); + + if(typeMap) typeMap.remove(object.id); + + object.dispose(); + } + } + + public removeAllObjects(): void + { + let i = 0; + + while(i < this._objects.length) + { + const object = this._objects.getWithIndex(i); + + if(object) object.dispose(); + + i++; + } + + this._objects.reset(); + + i = 0; + + while(i < this._objectsPerType.length) + { + const typeMap = this._objectsPerType.getWithIndex(i); + + if(typeMap) typeMap.dispose(); + + i++; + } + + this._objectsPerType.reset(); + } + + private getTypeMap(k: string, _arg_2: boolean = true): AdvancedMap + { + let existing = this._objectsPerType.getValue(k); + + if(!existing && _arg_2) + { + existing = new AdvancedMap(); + + this._objectsPerType.add(k, existing); + } + + return existing; + } + + public get objects(): AdvancedMap + { + return this._objects; + } + + public get totalObjects(): number + { + return this._objects.length; + } +} \ No newline at end of file diff --git a/src/room/data/RoomObjectSpriteData.ts b/src/room/data/RoomObjectSpriteData.ts new file mode 100644 index 00000000..768cae23 --- /dev/null +++ b/src/room/data/RoomObjectSpriteData.ts @@ -0,0 +1,18 @@ +export class RoomObjectSpriteData +{ + public objectId: number; + public x: number; + public y: number; + public z: number; + public name: string; + public blendMode: string; + public flipH: boolean; + public skew: number; + public frame: boolean; + public color: string; + public alpha: number; + public width: number; + public height: number; + public type: string; + public posture: string; +} diff --git a/src/room/events/RoomContentLoadedEvent.ts b/src/room/events/RoomContentLoadedEvent.ts new file mode 100644 index 00000000..a8033f8f --- /dev/null +++ b/src/room/events/RoomContentLoadedEvent.ts @@ -0,0 +1,22 @@ +import { NitroEvent } from '../../core/events/NitroEvent'; + +export class RoomContentLoadedEvent extends NitroEvent +{ + public static RCLE_SUCCESS: string = 'RCLE_SUCCESS'; + public static RCLE_FAILURE: string = 'RCLE_FAILURE'; + public static RCLE_CANCEL: string = 'RCLE_CANCEL'; + + private _contentType: string; + + constructor(type: string, contentType: string) + { + super(type); + + this._contentType = contentType; + } + + public get contentType(): string + { + return this._contentType; + } +} \ No newline at end of file diff --git a/src/room/events/RoomObjectEvent.ts b/src/room/events/RoomObjectEvent.ts new file mode 100644 index 00000000..c6c949d3 --- /dev/null +++ b/src/room/events/RoomObjectEvent.ts @@ -0,0 +1,33 @@ +import { NitroEvent } from '../../core/events/NitroEvent'; +import { IRoomObject } from '../object/IRoomObject'; + +export class RoomObjectEvent extends NitroEvent +{ + private _object: IRoomObject; + + constructor(type: string, object: IRoomObject) + { + super(type); + + this._object = object; + } + + public get object(): IRoomObject + { + return this._object; + } + + public get objectId(): number + { + if(!this._object) return -1; + + return this._object.id; + } + + public get objectType(): string + { + if(!this._object) return null; + + return this._object.type; + } +} \ No newline at end of file diff --git a/src/room/events/RoomObjectMouseEvent.ts b/src/room/events/RoomObjectMouseEvent.ts new file mode 100644 index 00000000..487e4d85 --- /dev/null +++ b/src/room/events/RoomObjectMouseEvent.ts @@ -0,0 +1,99 @@ +import { IRoomObject } from '../object/IRoomObject'; +import { RoomObjectEvent } from './RoomObjectEvent'; + +export class RoomObjectMouseEvent extends RoomObjectEvent +{ + public static CLICK: string = 'ROE_MOUSE_CLICK'; + public static DOUBLE_CLICK: string = 'ROE_MOUSE_DOUBLE_CLICK'; + public static MOUSE_MOVE: string = 'ROE_MOUSE_MOVE'; + public static MOUSE_DOWN: string = 'ROE_MOUSE_DOWN'; + public static MOUSE_UP: string = 'ROE_MOUSE_UP'; + public static MOUSE_ENTER: string = 'ROE_MOUSE_ENTER'; + public static MOUSE_LEAVE: string = 'ROE_MOUSE_LEAVE'; + + private _eventId: string = ''; + private _altKey: boolean; + private _ctrlKey: boolean; + private _shiftKey: boolean; + private _buttonDown: boolean; + private _localX: number; + private _localY: number; + private _spriteOffsetX: number; + private _spriteOffsetY: number; + + constructor(type: string, object: IRoomObject, eventId: string, altKey: boolean = false, ctrlKey: boolean = false, shiftKey: boolean = false, buttonDown: boolean = false) + { + super(type, object); + + this._eventId = eventId; + this._altKey = altKey; + this._ctrlKey = ctrlKey; + this._shiftKey = shiftKey; + this._buttonDown = buttonDown; + } + + public get eventId(): string + { + return this._eventId; + } + + public get altKey(): boolean + { + return this._altKey; + } + + public get ctrlKey(): boolean + { + return this._ctrlKey; + } + + public get shiftKey(): boolean + { + return this._shiftKey; + } + + public get buttonDown(): boolean + { + return this._buttonDown; + } + + public get localX(): number + { + return this._localX; + } + + public set localX(k: number) + { + this._localX = k; + } + + public get localY(): number + { + return this._localY; + } + + public set localY(k: number) + { + this._localY = k; + } + + public get spriteOffsetX(): number + { + return this._spriteOffsetX; + } + + public set spriteOffsetX(k: number) + { + this._spriteOffsetX = k; + } + + public get spriteOffsetY(): number + { + return this._spriteOffsetY; + } + + public set spriteOffsetY(k: number) + { + this._spriteOffsetY = k; + } +} \ No newline at end of file diff --git a/src/room/events/RoomSpriteMouseEvent.ts b/src/room/events/RoomSpriteMouseEvent.ts new file mode 100644 index 00000000..db2656d8 --- /dev/null +++ b/src/room/events/RoomSpriteMouseEvent.ts @@ -0,0 +1,115 @@ +export class RoomSpriteMouseEvent +{ + private _type: string; + private _eventId: string; + private _canvasId: string; + private _spriteTag: string; + private _screenX: number; + private _screenY: number; + private _localX: number; + private _localY: number; + private _ctrlKey: boolean; + private _altKey: boolean; + private _shiftKey: boolean; + private _buttonDown: boolean; + private _spriteOffsetX: number; + private _spriteOffsetY: number; + + constructor(type: string, eventId: string, canvasId: string, spriteTag: string, screenX: number, screenY: number, localX: number = 0, localY: number = 0, ctrlKey: boolean = false, altKey: boolean = false, shiftKey: boolean = false, buttonDown: boolean = false) + { + this._type = type; + this._eventId = eventId; + this._canvasId = canvasId; + this._spriteTag = spriteTag; + this._screenX = screenX; + this._screenY = screenY; + this._localX = localX; + this._localY = localY; + this._ctrlKey = ctrlKey; + this._altKey = altKey; + this._shiftKey = shiftKey; + this._buttonDown = buttonDown; + this._spriteOffsetX = 0; + this._spriteOffsetY = 0; + } + + public get type(): string + { + return this._type; + } + + public get _Str_3463(): string + { + return this._eventId; + } + + public get canvasId(): string + { + return this._canvasId; + } + + public get spriteTag(): string + { + return this._spriteTag; + } + + public get screenX(): number + { + return this._screenX; + } + + public get screenY(): number + { + return this._screenY; + } + + public get localX(): number + { + return this._localX; + } + + public get localY(): number + { + return this._localY; + } + + public get ctrlKey(): boolean + { + return this._ctrlKey; + } + + public get altKey(): boolean + { + return this._altKey; + } + + public get shiftKey(): boolean + { + return this._shiftKey; + } + + public get buttonDown(): boolean + { + return this._buttonDown; + } + + public get spriteOffsetX(): number + { + return this._spriteOffsetX; + } + + public set spriteOffsetX(k: number) + { + this._spriteOffsetX = k; + } + + public get spriteOffsetY(): number + { + return this._spriteOffsetY; + } + + public set spriteOffsetY(k: number) + { + this._spriteOffsetY = k; + } +} \ No newline at end of file diff --git a/src/room/events/RoomToObjectEvent.ts b/src/room/events/RoomToObjectEvent.ts new file mode 100644 index 00000000..aed45d91 --- /dev/null +++ b/src/room/events/RoomToObjectEvent.ts @@ -0,0 +1,9 @@ +import { NitroEvent } from '../../core/events/NitroEvent'; + +export class RoomToObjectEvent extends NitroEvent +{ + public constructor(type: string) + { + super(type); + } +} \ No newline at end of file diff --git a/src/room/messages/RoomObjectUpdateMessage.ts b/src/room/messages/RoomObjectUpdateMessage.ts new file mode 100644 index 00000000..80e7b63b --- /dev/null +++ b/src/room/messages/RoomObjectUpdateMessage.ts @@ -0,0 +1,23 @@ +import { IVector3D } from '../utils/IVector3D'; + +export class RoomObjectUpdateMessage +{ + private _location: IVector3D; + private _direction: IVector3D; + + constructor(location: IVector3D, direction: IVector3D) + { + this._location = location; + this._direction = direction; + } + + public get location(): IVector3D + { + return this._location; + } + + public get direction(): IVector3D + { + return this._direction; + } +} \ No newline at end of file diff --git a/src/room/object/IRoomObject.ts b/src/room/object/IRoomObject.ts new file mode 100644 index 00000000..7f3a3148 --- /dev/null +++ b/src/room/object/IRoomObject.ts @@ -0,0 +1,22 @@ +import { IDisposable } from '../../core/common/disposable/IDisposable'; +import { IVector3D } from '../utils/IVector3D'; +import { IRoomObjectModel } from './IRoomObjectModel'; +import { IRoomObjectMouseHandler } from './logic/IRoomObjectMouseHandler'; +import { IRoomObjectVisualization } from './visualization/IRoomObjectVisualization'; + +export interface IRoomObject extends IDisposable +{ + getLocation(): IVector3D; + getDirection(): IVector3D; + getState(index?: number): number; + id: number; + instanceId: number; + type: string; + model: IRoomObjectModel; + visualization: IRoomObjectVisualization; + mouseHandler: IRoomObjectMouseHandler; + location: IVector3D; + direction: IVector3D; + updateCounter: number; + isReady: boolean; +} \ No newline at end of file diff --git a/src/room/object/IRoomObjectController.ts b/src/room/object/IRoomObjectController.ts new file mode 100644 index 00000000..6e4a7e94 --- /dev/null +++ b/src/room/object/IRoomObjectController.ts @@ -0,0 +1,18 @@ +import { RoomObjectUpdateMessage } from '../messages/RoomObjectUpdateMessage'; +import { IVector3D } from '../utils/IVector3D'; +import { IRoomObject } from './IRoomObject'; +import { IRoomObjectEventHandler } from './logic/IRoomObjectEventHandler'; +import { IRoomObjectGraphicVisualization } from './visualization/IRoomObjectGraphicVisualization'; + +export interface IRoomObjectController extends IRoomObject +{ + setLocation(vector: IVector3D): void; + setDirection(vector: IVector3D): void; + setState(state: number, index?: number): boolean; + setVisualization(visualization: IRoomObjectGraphicVisualization): void; + setLogic(logic: IRoomObjectEventHandler): void; + processUpdateMessage(message: RoomObjectUpdateMessage): void; + tearDown(): void; + isReady: boolean; + logic: IRoomObjectEventHandler; +} \ No newline at end of file diff --git a/src/room/object/IRoomObjectModel.ts b/src/room/object/IRoomObjectModel.ts new file mode 100644 index 00000000..64291ed6 --- /dev/null +++ b/src/room/object/IRoomObjectModel.ts @@ -0,0 +1,8 @@ +export interface IRoomObjectModel +{ + dispose(): void; + getValue(key: string): T; + setValue(key: string, value: T): void; + removeKey(key: string): void; + updateCounter: number; +} \ No newline at end of file diff --git a/src/room/object/IRoomObjectModelController.ts b/src/room/object/IRoomObjectModelController.ts new file mode 100644 index 00000000..2c1113e9 --- /dev/null +++ b/src/room/object/IRoomObjectModelController.ts @@ -0,0 +1,11 @@ +import { IRoomObjectModel } from './IRoomObjectModel'; +import { AdvancedMap } from '../../core/utils/AdvancedMap'; + +export interface IRoomObjectModelController extends IRoomObjectModel +{ + setNumber(_arg_1: string, _arg_2: number, _arg_3: boolean): void; + setString(_arg_1: string, _arg_2: string, _arg_3: boolean): void; + setNumberArray(_arg_1: string, _arg_2: [], _arg_3: boolean): void; + setStringArray(_arg_1: string, _arg_2: [], _arg_3: boolean): void; + setStringToStringMap(_arg_1: string, _arg_2: AdvancedMap, _arg_3: boolean): void; +} diff --git a/src/room/object/RoomObject.ts b/src/room/object/RoomObject.ts new file mode 100644 index 00000000..34d8c08a --- /dev/null +++ b/src/room/object/RoomObject.ts @@ -0,0 +1,252 @@ +import { Disposable } from '../../core/common/disposable/Disposable'; +import { RoomObjectUpdateMessage } from '../messages/RoomObjectUpdateMessage'; +import { IVector3D } from '../utils/IVector3D'; +import { Vector3d } from '../utils/Vector3d'; +import { IRoomObjectController } from './IRoomObjectController'; +import { IRoomObjectModel } from './IRoomObjectModel'; +import { IRoomObjectEventHandler } from './logic/IRoomObjectEventHandler'; +import { IRoomObjectMouseHandler } from './logic/IRoomObjectMouseHandler'; +import { RoomObjectModel } from './RoomObjectModel'; +import { IRoomObjectVisualization } from './visualization/IRoomObjectVisualization'; + +export class RoomObject extends Disposable implements IRoomObjectController +{ + private static OBJECT_COUNTER: number = 0; + + private _id: number; + private _instanceId: number; + private _type: string; + private _model: IRoomObjectModel; + + private _location: IVector3D; + private _direction: IVector3D; + private _states: number[]; + + private _visualization: IRoomObjectVisualization; + private _logic: IRoomObjectEventHandler; + private _pendingLogicMessages: RoomObjectUpdateMessage[]; + + private _updateCounter: number; + private _isReady: boolean; + + constructor(id: number, stateCount: number, type: string) + { + super(); + + this._id = id; + this._instanceId = RoomObject.OBJECT_COUNTER++; + this._type = type; + this._model = new RoomObjectModel(); + + this._location = new Vector3d(); + this._direction = new Vector3d(); + this._states = []; + + this._visualization = null; + this._logic = null; + this._pendingLogicMessages = []; + + this._updateCounter = 0; + this._isReady = false; + + let i = (stateCount - 1); + + while(i >= 0) + { + this._states[i] = 0; + + i--; + } + } + + protected onDispose(): void + { + this._pendingLogicMessages = []; + + this.setVisualization(null); + this.setLogic(null); + + if(this._model) this._model.dispose(); + + super.onDispose(); + } + + public getLocation(): IVector3D + { + return this._location; + } + + public setLocation(vector: IVector3D): void + { + if(!vector) return; + + if((vector.x === this._location.x) && (vector.y === this._location.y) && (vector.z === this._location.z)) return; + + this._location.x = vector.x; + this._location.y = vector.y; + this._location.z = vector.z; + + this._updateCounter++; + } + + public getDirection(): IVector3D + { + return this._direction; + } + + public setDirection(vector: IVector3D): void + { + if(!vector) return; + + if((vector.x === this._direction.x) && (vector.y === this._direction.y) && (vector.z === this._direction.z)) return; + + this._direction.x = (((vector.x % 360) + 360) % 360); + this._direction.y = (((vector.y % 360) + 360) % 360); + this._direction.z = (((vector.z % 360) + 360) % 360); + + this._updateCounter++; + } + + public getState(index: number = 0): number + { + if((index >= 0) && (index < this._states.length)) + { + return this._states[index]; + } + + return -1; + } + + public setState(state: number, index: number = 0): boolean + { + if((index >= 0) && (index < this._states.length)) + { + if(this._states[index] !== state) + { + this._states[index] = state; + + this._updateCounter++; + } + + return true; + } + + return false; + } + + public setVisualization(visualization: IRoomObjectVisualization): void + { + if(this._visualization === visualization) return; + + if(this._visualization) this._visualization.dispose(); + + this._visualization = visualization; + + if(this._visualization) this._visualization.object = this; + } + + public setLogic(logic: IRoomObjectEventHandler): void + { + if(this._logic === logic) return; + + const eventHandler = this._logic; + + if(eventHandler) + { + this._logic = null; + + eventHandler.setObject(null); + } + + this._logic = logic; + + if(this._logic) + { + this._logic.setObject(this); + + while(this._pendingLogicMessages.length) + { + const message = this._pendingLogicMessages.shift(); + + this._logic.processUpdateMessage(message); + } + } + } + + public processUpdateMessage(message: RoomObjectUpdateMessage): void + { + if(this._logic) return this._logic.processUpdateMessage(message); + + this._pendingLogicMessages.push(message); + } + + public tearDown(): void + { + if(this._logic) this._logic.tearDown(); + } + + public get id(): number + { + return this._id; + } + + public get instanceId(): number + { + return this._instanceId; + } + + public get type(): string + { + return this._type; + } + + public get model(): IRoomObjectModel + { + return this._model; + } + + public get visualization(): IRoomObjectVisualization + { + return this._visualization; + } + + public get mouseHandler(): IRoomObjectMouseHandler + { + return this._logic as IRoomObjectMouseHandler; + } + + public get logic(): IRoomObjectEventHandler + { + return this._logic; + } + + public get location(): IVector3D + { + return this._location; + } + + public get direction(): IVector3D + { + return this._direction; + } + + public get updateCounter(): number + { + return this._updateCounter; + } + + public set updateCounter(count: number) + { + this._updateCounter = count; + } + + public get isReady(): boolean + { + return this._isReady; + } + + public set isReady(flag: boolean) + { + this._isReady = flag; + } +} \ No newline at end of file diff --git a/src/room/object/RoomObjectModel.ts b/src/room/object/RoomObjectModel.ts new file mode 100644 index 00000000..dadba40e --- /dev/null +++ b/src/room/object/RoomObjectModel.ts @@ -0,0 +1,48 @@ +import { IRoomObjectModel } from './IRoomObjectModel'; + +export class RoomObjectModel implements IRoomObjectModel +{ + private _map: Map; + private _updateCounter: number; + + constructor() + { + this._map = new Map(); + this._updateCounter = 0; + } + + public dispose(): void + { + this._map.clear(); + + this._updateCounter = 0; + } + + public getValue(key: string): T + { + const existing = this._map.get(key); + + return (existing as T); + } + + public setValue(key: string, value: T): void + { + this._map.set(key, (value as T)); + + this._updateCounter++; + } + + public removeKey(key: string): void + { + if(!key) return; + + this._map.delete(key); + + this._updateCounter++; + } + + public get updateCounter(): number + { + return this._updateCounter; + } +} \ No newline at end of file diff --git a/src/room/object/enum/AlphaTolerance.ts b/src/room/object/enum/AlphaTolerance.ts new file mode 100644 index 00000000..a65d6fd2 --- /dev/null +++ b/src/room/object/enum/AlphaTolerance.ts @@ -0,0 +1,6 @@ +export class AlphaTolerance +{ + public static _Str_16646: number = -1; + public static _Str_9735: number = 128; + public static _Str_9268: number = 256; +} \ No newline at end of file diff --git a/src/room/object/enum/RoomObjectSpriteType.ts b/src/room/object/enum/RoomObjectSpriteType.ts new file mode 100644 index 00000000..92bbbb1f --- /dev/null +++ b/src/room/object/enum/RoomObjectSpriteType.ts @@ -0,0 +1,7 @@ +export class RoomObjectSpriteType +{ + public static DEFAULT: number = 1; + public static _Str_8616: number = 2; + public static _Str_11629: number = 3; + public static _Str_10494: number = 4; +} \ No newline at end of file diff --git a/src/room/object/logic/IRoomObjectEventHandler.ts b/src/room/object/logic/IRoomObjectEventHandler.ts new file mode 100644 index 00000000..e0e87b0c --- /dev/null +++ b/src/room/object/logic/IRoomObjectEventHandler.ts @@ -0,0 +1,20 @@ +import { IDisposable } from '../../../core/common/disposable/IDisposable'; +import { IEventDispatcher } from '../../../core/events/IEventDispatcher'; +import { RoomObjectUpdateMessage } from '../../messages/RoomObjectUpdateMessage'; +import { IRoomObjectController } from '../IRoomObjectController'; +import { IRoomObjectMouseHandler } from './IRoomObjectMouseHandler'; + +export interface IRoomObjectEventHandler extends IRoomObjectMouseHandler, IDisposable +{ + initialize(data: unknown): void; + update(totalTimeRunning: number): void; + processUpdateMessage(message: RoomObjectUpdateMessage): void; + getEventTypes(): string[]; + useObject(): void; + setObject(object: IRoomObjectController): void; + tearDown(): void; + object: IRoomObjectController; + eventDispatcher: IEventDispatcher; + widget: string; + contextMenu: string; +} \ No newline at end of file diff --git a/src/room/object/logic/IRoomObjectLogicFactory.ts b/src/room/object/logic/IRoomObjectLogicFactory.ts new file mode 100644 index 00000000..9054553d --- /dev/null +++ b/src/room/object/logic/IRoomObjectLogicFactory.ts @@ -0,0 +1,10 @@ +import { IEventDispatcher } from '../../../core/events/IEventDispatcher'; +import { IRoomObjectEventHandler } from './IRoomObjectEventHandler'; + +export interface IRoomObjectLogicFactory +{ + getLogic(type: string): IRoomObjectEventHandler; + registerEventFunction(func: Function): void; + removeEventFunction(func: Function): void; + events: IEventDispatcher; +} \ No newline at end of file diff --git a/src/room/object/logic/IRoomObjectMouseHandler.ts b/src/room/object/logic/IRoomObjectMouseHandler.ts new file mode 100644 index 00000000..676faba8 --- /dev/null +++ b/src/room/object/logic/IRoomObjectMouseHandler.ts @@ -0,0 +1,7 @@ +import { RoomSpriteMouseEvent } from '../../events/RoomSpriteMouseEvent'; +import { IRoomGeometry } from '../../utils/IRoomGeometry'; + +export interface IRoomObjectMouseHandler +{ + mouseEvent(event: RoomSpriteMouseEvent, geometry: IRoomGeometry): void; +} \ No newline at end of file diff --git a/src/room/object/logic/RoomObjectLogicBase.ts b/src/room/object/logic/RoomObjectLogicBase.ts new file mode 100644 index 00000000..f86b6d9b --- /dev/null +++ b/src/room/object/logic/RoomObjectLogicBase.ts @@ -0,0 +1,136 @@ +import { Disposable } from '../../../core/common/disposable/Disposable'; +import { IEventDispatcher } from '../../../core/events/IEventDispatcher'; +import { RoomSpriteMouseEvent } from '../../events/RoomSpriteMouseEvent'; +import { RoomObjectUpdateMessage } from '../../messages/RoomObjectUpdateMessage'; +import { IRoomGeometry } from '../../utils/IRoomGeometry'; +import { IRoomObjectController } from '../IRoomObjectController'; +import { IRoomObjectEventHandler } from './IRoomObjectEventHandler'; + +export class RoomObjectLogicBase extends Disposable implements IRoomObjectEventHandler +{ + private _events: IEventDispatcher; + private _object: IRoomObjectController; + + private _time: number; + + constructor() + { + super(); + + this._object = null; + this._events = null; + + this._time = 0; + } + + public initialize(data: unknown): void + { + return; + } + + protected onDispose(): void + { + this._object = null; + } + + public update(time: number): void + { + this._time = time; + + return; + } + + public processUpdateMessage(message: RoomObjectUpdateMessage): void + { + if(!message || !this._object) return; + + this._object.setLocation(message.location); + this._object.setDirection(message.direction); + } + + public getEventTypes(): string[] + { + return []; + } + + protected mergeTypes(k: string[], _arg_2: string[]): string[] + { + const types = k.concat(); + + for(const type of _arg_2) + { + if(!type || (types.indexOf(type) >= 0)) continue; + + types.push(type); + } + + return types; + } + + public mouseEvent(event: RoomSpriteMouseEvent, geometry: IRoomGeometry): void + { + return; + } + + public useObject(): void + { + return; + } + + public setObject(object: IRoomObjectController): void + { + if(this._object === object) return; + + if(this._object) + { + this._object.setLogic(null); + } + + if(!object) + { + this.dispose(); + + this._object = null; + + return; + } + + this._object = object; + this._object.setLogic(this); + } + + public tearDown(): void + { + return; + } + + public get object(): IRoomObjectController + { + return this._object; + } + + public get eventDispatcher(): IEventDispatcher + { + return this._events; + } + + public set eventDispatcher(events: IEventDispatcher) + { + this._events = events; + } + + public get widget(): string + { + return null; + } + + public get contextMenu(): string + { + return null; + } + + public get time(): number + { + return this._time; + } +} \ No newline at end of file diff --git a/src/room/object/visualization/IPlaneDrawingData.ts b/src/room/object/visualization/IPlaneDrawingData.ts new file mode 100644 index 00000000..c043e177 --- /dev/null +++ b/src/room/object/visualization/IPlaneDrawingData.ts @@ -0,0 +1,14 @@ +import { Point } from 'pixi.js'; + +export interface IPlaneDrawingData +{ + _Str_14945(): boolean; + z: number; + cornerPoints: Point[]; + color: number; + _Str_21807: string[]; + _Str_20731: Point[]; + _Str_21810: boolean[]; + _Str_19044: boolean[]; + _Str_17636: string[][]; +} \ No newline at end of file diff --git a/src/room/object/visualization/IPlaneVisualization.ts b/src/room/object/visualization/IPlaneVisualization.ts new file mode 100644 index 00000000..f0602772 --- /dev/null +++ b/src/room/object/visualization/IPlaneVisualization.ts @@ -0,0 +1,6 @@ +import { IRoomPlane } from './IRoomPlane'; + +export interface IPlaneVisualization +{ + _Str_19113: IRoomPlane[]; +} \ No newline at end of file diff --git a/src/room/object/visualization/IRoomObjectGraphicVisualization.ts b/src/room/object/visualization/IRoomObjectGraphicVisualization.ts new file mode 100644 index 00000000..ffef37c6 --- /dev/null +++ b/src/room/object/visualization/IRoomObjectGraphicVisualization.ts @@ -0,0 +1,7 @@ +import { IRoomObjectVisualization } from './IRoomObjectVisualization'; +import { IGraphicAssetCollection } from './utils/IGraphicAssetCollection'; + +export interface IRoomObjectGraphicVisualization extends IRoomObjectVisualization +{ + asset: IGraphicAssetCollection; +} \ No newline at end of file diff --git a/src/room/object/visualization/IRoomObjectSprite.ts b/src/room/object/visualization/IRoomObjectSprite.ts new file mode 100644 index 00000000..de50bf6a --- /dev/null +++ b/src/room/object/visualization/IRoomObjectSprite.ts @@ -0,0 +1,32 @@ +import { Container, Filter, Texture } from 'pixi.js'; + +export interface IRoomObjectSprite +{ + id: number; + name: string; + type: string; + spriteType: number; + texture: Texture; + container: Container; + width: number; + height: number; + offsetX: number; + offsetY: number; + flipH: boolean; + flipV: boolean; + direction: number; + alpha: number; + blendMode: number; + color: number; + relativeDepth: number; + _Str_4593: boolean; + _Str_3582: string; + clickHandling: boolean; + visible: boolean; + tag: string; + posture: string; + alphaTolerance: number; + filters: Filter[]; + updateCounter: number; + updateContainer: boolean; +} \ No newline at end of file diff --git a/src/room/object/visualization/IRoomObjectSpriteVisualization.ts b/src/room/object/visualization/IRoomObjectSpriteVisualization.ts new file mode 100644 index 00000000..b30acde9 --- /dev/null +++ b/src/room/object/visualization/IRoomObjectSpriteVisualization.ts @@ -0,0 +1,12 @@ +import { RoomObjectSpriteData } from '../../data/RoomObjectSpriteData'; +import { IRoomObjectGraphicVisualization } from './IRoomObjectGraphicVisualization'; +import { IRoomObjectSprite } from './IRoomObjectSprite'; + +export interface IRoomObjectSpriteVisualization extends IRoomObjectGraphicVisualization +{ + getSprite(index: number): IRoomObjectSprite; + getSpriteList(): RoomObjectSpriteData[]; + sprites: IRoomObjectSprite[]; + updateObjectCounter: number; + updateModelCounter: number; +} \ No newline at end of file diff --git a/src/room/object/visualization/IRoomObjectVisualization.ts b/src/room/object/visualization/IRoomObjectVisualization.ts new file mode 100644 index 00000000..5f2a09b5 --- /dev/null +++ b/src/room/object/visualization/IRoomObjectVisualization.ts @@ -0,0 +1,17 @@ +import { Rectangle, RenderTexture, Texture } from 'pixi.js'; +import { IRoomGeometry } from '../../utils/IRoomGeometry'; +import { IRoomObject } from '../IRoomObject'; +import { IObjectVisualizationData } from './IRoomObjectVisualizationData'; + +export interface IRoomObjectVisualization +{ + initialize(data: IObjectVisualizationData): boolean; + dispose(): void; + update(geometry: IRoomGeometry, time: number, update: boolean, skipUpdate: boolean): void; + getBoundingRectangle(): Rectangle; + getImage(bgColor: number, originalId: number): RenderTexture; + instanceId: number; + object: IRoomObject; + image: Texture; + updateSpriteCounter: number; +} \ No newline at end of file diff --git a/src/room/object/visualization/IRoomObjectVisualizationData.ts b/src/room/object/visualization/IRoomObjectVisualizationData.ts new file mode 100644 index 00000000..06704411 --- /dev/null +++ b/src/room/object/visualization/IRoomObjectVisualizationData.ts @@ -0,0 +1,7 @@ +import { IAssetData } from '../../../core/asset/interfaces'; + +export interface IObjectVisualizationData +{ + initialize(asset: IAssetData): boolean; + dispose(): void; +} \ No newline at end of file diff --git a/src/room/object/visualization/IRoomObjectVisualizationFactory.ts b/src/room/object/visualization/IRoomObjectVisualizationFactory.ts new file mode 100644 index 00000000..6c988221 --- /dev/null +++ b/src/room/object/visualization/IRoomObjectVisualizationFactory.ts @@ -0,0 +1,9 @@ +import { IAssetData } from '../../../core/asset/interfaces'; +import { IRoomObjectGraphicVisualization } from './IRoomObjectGraphicVisualization'; +import { IObjectVisualizationData } from './IRoomObjectVisualizationData'; + +export interface IRoomObjectVisualizationFactory +{ + getVisualization(type: string): IRoomObjectGraphicVisualization; + getVisualizationData(type: string, visualization: string, asset: IAssetData): IObjectVisualizationData; +} \ No newline at end of file diff --git a/src/room/object/visualization/IRoomPlane.ts b/src/room/object/visualization/IRoomPlane.ts new file mode 100644 index 00000000..881c2868 --- /dev/null +++ b/src/room/object/visualization/IRoomPlane.ts @@ -0,0 +1,13 @@ +import { PlaneDrawingData } from '../../../nitro/room/object/visualization/room/PlaneDrawingData'; +import { IRoomGeometry } from '../../utils/IRoomGeometry'; +import { IVector3D } from '../../utils/IVector3D'; + +export interface IRoomPlane +{ + uniqueId: number; + location: IVector3D; + _Str_5424: IVector3D; + _Str_4968: IVector3D; + color: number; + _Str_22136(_arg_1: IRoomGeometry): PlaneDrawingData[]; +} \ No newline at end of file diff --git a/src/room/object/visualization/ISortableSprite.ts b/src/room/object/visualization/ISortableSprite.ts new file mode 100644 index 00000000..b4c0e75f --- /dev/null +++ b/src/room/object/visualization/ISortableSprite.ts @@ -0,0 +1,9 @@ +import { IRoomObjectSprite } from './IRoomObjectSprite'; + +export interface ISortableSprite +{ + x: number; + y: number; + z: number; + sprite: IRoomObjectSprite; +} \ No newline at end of file diff --git a/src/room/object/visualization/RoomObjectSprite.ts b/src/room/object/visualization/RoomObjectSprite.ts new file mode 100644 index 00000000..386b71cc --- /dev/null +++ b/src/room/object/visualization/RoomObjectSprite.ts @@ -0,0 +1,422 @@ +import { BLEND_MODES, Container, Filter, Texture } from 'pixi.js'; +import { AlphaTolerance } from '../enum/AlphaTolerance'; +import { RoomObjectSpriteType } from '../enum/RoomObjectSpriteType'; +import { IRoomObjectSprite } from './IRoomObjectSprite'; + +export class RoomObjectSprite implements IRoomObjectSprite +{ + private static SPRITE_COUNTER: number = 0; + + private _id: number; + private _name: string; + private _type: string; + private _spriteType: number; + private _texture: Texture; + private _container: Container; + + private _width: number; + private _height: number; + private _offsetX: number; + private _offsetY: number; + private _flipH: boolean; + private _flipV: boolean; + private _direction: number; + + private _alpha: number; + private _blendMode: number; + private _color: number; + private _relativeDepth: number; + private _Str_8253: boolean; + private _Str_11397: string; + private _clickHandling: boolean; + private _visible: boolean; + private _tag: string; + private _posture: string; + private _alphaTolerance: number; + private _filters: Filter[]; + + private _updateCounter: number; + private _updateContainer: boolean; + + constructor() + { + this._id = RoomObjectSprite.SPRITE_COUNTER++; + this._name = ''; + this._type = ''; + this._spriteType = RoomObjectSpriteType.DEFAULT; + this._texture = null; + this._container = null; + + this._width = 0; + this._height = 0; + this._offsetX = 0; + this._offsetY = 0; + this._flipH = false; + this._flipV = false; + this._direction = 0; + + this._alpha = 255; + this._blendMode = BLEND_MODES.NORMAL; + this._color = 0xFFFFFF; + this._relativeDepth = 0; + this._Str_8253 = false; + this._Str_11397 = ''; + this._clickHandling = false; + this._visible = true; + this._tag = ''; + this._posture = null; + this._alphaTolerance = AlphaTolerance._Str_9735; + this._filters = []; + + this._updateCounter = 0; + this._updateContainer = false; + } + + public dispose(): void + { + this._texture = null; + this._width = 0; + this._height = 0; + } + + public get id(): number + { + return this._id; + } + + public set id(id: number) + { + this._id = id; + } + + public get name(): string + { + return this._name; + } + + public set name(name: string) + { + if(this._name === name) return; + + this._name = name; + + this._updateCounter++; + } + + public get type(): string + { + return this._type; + } + + public set type(type: string) + { + this._type = type; + } + + public get spriteType(): number + { + return this._spriteType; + } + + public set spriteType(type: number) + { + this._spriteType = type; + } + + public get texture(): Texture + { + return this._texture; + } + + public set texture(texture: Texture) + { + if(this._texture === texture) return; + + if(texture) + { + this._width = texture.width; + this._height = texture.height; + } + + this._texture = texture; + + this._updateCounter++; + } + + public get container(): Container + { + return this._container; + } + + public set container(container: Container) + { + if(this._container === container) return; + + this.texture = Texture.EMPTY; + + if(container) + { + this._width = container.width; + this._height = container.height; + } + + this._container = container; + + this._updateCounter++; + + this._updateContainer = true; + } + + public get width(): number + { + return this._width; + } + + public get height(): number + { + return this._height; + } + + public get offsetX(): number + { + return this._offsetX; + } + + public set offsetX(x: number) + { + if(this._offsetX === x) return; + + this._offsetX = x; + + this._updateCounter++; + } + + public get offsetY(): number + { + return this._offsetY; + } + + public set offsetY(y: number) + { + if(this._offsetY === y) return; + + this._offsetY = y; + + this._updateCounter++; + } + + public get flipH(): boolean + { + return this._flipH; + } + + public set flipH(flip: boolean) + { + if(this._flipH === flip) return; + + this._flipH = flip; + + this._updateCounter++; + } + + public get flipV(): boolean + { + return this._flipV; + } + + public set flipV(flip: boolean) + { + if(this._flipV === flip) return; + + this._flipV = flip; + + this._updateCounter++; + } + + public get direction(): number + { + return this._direction; + } + + public set direction(direction: number) + { + this._direction = direction; + } + + public get alpha(): number + { + return this._alpha; + } + + public set alpha(alpha: number) + { + alpha = (alpha & 0xFF); + + if(this._alpha === alpha) return; + + this._alpha = alpha; + + this._updateCounter++; + } + + public get blendMode(): number + { + return this._blendMode; + } + + public set blendMode(blend: number) + { + if(this._blendMode === blend) return; + + this._blendMode = blend; + + this._updateCounter++; + } + + public get color(): number + { + return this._color; + } + + public set color(color: number) + { + color = (color & 0xFFFFFF); + + if(this._color === color) return; + + this._color = color; + + this._updateCounter++; + } + + public get relativeDepth(): number + { + return this._relativeDepth; + } + + public set relativeDepth(depth: number) + { + if(this._relativeDepth === depth) return; + + this._relativeDepth = depth; + + this._updateCounter++; + } + + public get _Str_4593(): boolean + { + return this._Str_8253; + } + + public set _Str_4593(flag: boolean) + { + if(flag === this._Str_8253) return; + + this._Str_8253 = flag; + + this._updateCounter++; + } + + public get _Str_3582(): string + { + return this._Str_11397; + } + + public set _Str_3582(value: string) + { + this._Str_11397 = value; + } + + public get clickHandling(): boolean + { + return this._clickHandling; + } + + public set clickHandling(flag: boolean) + { + this._clickHandling = flag; + } + + public get visible(): boolean + { + return this._visible; + } + + public set visible(visible: boolean) + { + if(this._visible === visible) return; + + this._visible = visible; + + this._updateCounter++; + } + + public get tag(): string + { + return this._tag; + } + + public set tag(tag: string) + { + if(this._tag === tag) return; + + this._tag = tag; + + this._updateCounter++; + } + + public get posture(): string + { + return this._posture; + } + + public set posture(posture: string) + { + if(this._posture === posture) return; + + this._posture = posture; + + this._updateCounter++; + } + + public get alphaTolerance(): number + { + return this._alphaTolerance; + } + + public set alphaTolerance(tolerance: number) + { + if(this._alphaTolerance === tolerance) return; + + this._alphaTolerance = tolerance; + + this._updateCounter++; + } + + public get filters(): Filter[] + { + return this._filters; + } + + public set filters(filters: Filter[]) + { + this._filters = filters; + + this._updateCounter++; + } + + public get updateCounter(): number + { + return this._updateCounter; + } + + public get updateContainer(): boolean + { + return this._updateContainer; + } + + public set updateContainer(flag: boolean) + { + this._updateContainer = flag; + } +} \ No newline at end of file diff --git a/src/room/object/visualization/RoomObjectSpriteVisualization.ts b/src/room/object/visualization/RoomObjectSpriteVisualization.ts new file mode 100644 index 00000000..8a56781e --- /dev/null +++ b/src/room/object/visualization/RoomObjectSpriteVisualization.ts @@ -0,0 +1,309 @@ +import { Container, Point, Rectangle, RenderTexture, Sprite } from 'pixi.js'; +import { RoomObjectSpriteData } from '../../data/RoomObjectSpriteData'; +import { IRoomGeometry } from '../../utils/IRoomGeometry'; +import { TextureUtils } from '../../utils/TextureUtils'; +import { IRoomObjectController } from '../IRoomObjectController'; +import { IRoomObjectSprite } from './IRoomObjectSprite'; +import { IRoomObjectSpriteVisualization } from './IRoomObjectSpriteVisualization'; +import { IObjectVisualizationData } from './IRoomObjectVisualizationData'; +import { RoomObjectSprite } from './RoomObjectSprite'; +import { IGraphicAssetCollection } from './utils/IGraphicAssetCollection'; + +export class RoomObjectSpriteVisualization implements IRoomObjectSpriteVisualization +{ + private static VISUALIZATION_COUNTER: number = 0; + + private _id: number; + private _object: IRoomObjectController; + private _asset: IGraphicAssetCollection; + private _sprites: IRoomObjectSprite[]; + + protected _scale: number; + + private _updateObjectCounter: number; + private _updateModelCounter: number; + private _updateSpriteCounter: number; + + constructor() + { + this._id = RoomObjectSpriteVisualization.VISUALIZATION_COUNTER++; + this._object = null; + this._asset = null; + this._sprites = []; + + this._scale = -1; + + this._updateObjectCounter = -1; + this._updateModelCounter = -1; + this._updateSpriteCounter = -1; + } + + public initialize(data: IObjectVisualizationData): boolean + { + return false; + } + + public update(geometry: IRoomGeometry, time: number, update: boolean, skipUpdate: boolean): void + { + return; + } + + protected reset(): void + { + this._scale = -1; + } + + public dispose(): void + { + if(this._sprites) + { + while(this._sprites.length) + { + const sprite = (this._sprites[0] as RoomObjectSprite); + + if(sprite) sprite.dispose(); + + this._sprites.pop(); + } + + this._sprites = null; + } + + this._object = null; + this._asset = null; + } + + public getSprite(index: number): IRoomObjectSprite + { + if((index >= 0) && (index < this._sprites.length)) return this._sprites[index]; + + return null; + } + + public getSpriteList(): RoomObjectSpriteData[] + { + return null; + } + + public createSprite(): IRoomObjectSprite + { + return this.createSpriteAtIndex(this._sprites.length); + } + + public createSpriteAtIndex(index: number): IRoomObjectSprite + { + const sprite = new RoomObjectSprite(); + + if(index >= this._sprites.length) + { + this._sprites.push(sprite); + } + else + { + this._sprites.splice(index, 0, sprite); + } + + return sprite; + } + + protected setSpriteCount(count: number): void + { + while(this._sprites.length > count) + { + const sprite = this._sprites[(this._sprites.length - 1)] as RoomObjectSprite; + + if(sprite) sprite.dispose(); + + this._sprites.pop(); + } + + while(this._sprites.length < count) + { + this._sprites.push(new RoomObjectSprite()); + } + } + + public get image(): RenderTexture + { + return this.getImage(0, -1); + } + + public getImage(bgColor: number, originalId: number): RenderTexture + { + const boundingRectangle = this.getBoundingRectangle(); + + if((boundingRectangle.width * boundingRectangle.height) === 0) return null; + + const spriteCount = this.totalSprites; + const spriteList: IRoomObjectSprite[] = []; + + let index = 0; + + while(index < spriteCount) + { + const objectSprite = this.getSprite(index); + + if(objectSprite && objectSprite.visible && objectSprite.texture) spriteList.push(objectSprite); + + index++; + } + + spriteList.sort((a, b) => + { + return b.relativeDepth - a.relativeDepth; + }); + + const container = new Container(); + + index = 0; + + while(index < spriteList.length) + { + const objectSprite = spriteList[index]; + const texture = objectSprite.texture; + + if(texture) + { + const sprite = Sprite.from(texture); + + sprite.alpha = (objectSprite.alpha / 255); + sprite.tint = objectSprite.color; + sprite.x = objectSprite.offsetX; + sprite.y = objectSprite.offsetY; + sprite.blendMode = objectSprite.blendMode; + sprite.filters = objectSprite.filters; + + if(objectSprite.flipH) sprite.scale.x = -1; + + if(objectSprite.flipV) sprite.scale.y = -1; + + container.addChild(sprite); + } + + index++; + } + + const texture = TextureUtils.generateTexture(container); + + if(!texture) return null; + + return texture; + } + + public getBoundingRectangle(): Rectangle + { + const totalSprites = this.totalSprites; + const rectangle = new Rectangle(); + + let iterator = 0; + + while(iterator < totalSprites) + { + const sprite = this.getSprite(iterator); + + if(sprite && sprite.texture && sprite.visible) + { + const offsetX = ((sprite.flipH) ? (-(sprite.width) + sprite.offsetX) : sprite.offsetX); + const offsetY = ((sprite.flipV) ? (-(sprite.height) + sprite.offsetY) : sprite.offsetY); + + const point = new Point(offsetX, offsetY); + + if(iterator === 0) + { + rectangle.x = point.x; + rectangle.y = point.y; + rectangle.width = sprite.width; + rectangle.height = sprite.height; + } + else + { + if(point.x < rectangle.x) rectangle.x = point.x; + + if(point.y < rectangle.y) rectangle.y = point.y; + + if((point.x + sprite.width) > rectangle.right) rectangle.width = ((point.x + sprite.width) - rectangle.x); + + if((point.y + sprite.height) > rectangle.bottom) rectangle.height = ((point.y + sprite.height) - rectangle.y); + } + } + + iterator++; + } + + return rectangle; + } + + public get instanceId(): number + { + return this._id; + } + + public get object(): IRoomObjectController + { + return this._object; + } + + public set object(object: IRoomObjectController) + { + this._object = object; + } + + public get asset(): IGraphicAssetCollection + { + return this._asset; + } + + public set asset(asset: IGraphicAssetCollection) + { + if(this._asset) this._asset.removeReference(); + + this._asset = asset; + + if(this._asset) this._asset.addReference(); + } + + public get sprites(): IRoomObjectSprite[] + { + return this._sprites; + } + + public get totalSprites(): number + { + return this._sprites.length; + } + + public get updateObjectCounter(): number + { + return this._updateObjectCounter; + } + + public set updateObjectCounter(count: number) + { + this._updateObjectCounter = count; + } + + public get updateModelCounter(): number + { + return this._updateModelCounter; + } + + public set updateModelCounter(count: number) + { + this._updateModelCounter = count; + } + + public get updateSpriteCounter(): number + { + return this._updateSpriteCounter; + } + + public set updateSpriteCounter(count: number) + { + this._updateSpriteCounter = count; + } + + public get spriteCount(): number + { + return this._sprites.length; + } +} diff --git a/src/room/object/visualization/utils/GraphicAsset.ts b/src/room/object/visualization/utils/GraphicAsset.ts new file mode 100644 index 00000000..5f34b765 --- /dev/null +++ b/src/room/object/visualization/utils/GraphicAsset.ts @@ -0,0 +1,140 @@ +import { Rectangle, Texture } from 'pixi.js'; +import { IGraphicAsset } from './IGraphicAsset'; + +export class GraphicAsset implements IGraphicAsset +{ + private static GRAPHIC_POOL: GraphicAsset[] = []; + + private _name: string; + private _source: string; + private _texture: Texture; + private _usesPalette: boolean; + private _x: number; + private _y: number; + private _width: number; + private _height: number; + private _flipH: boolean; + private _flipV: boolean; + private _rectangle: Rectangle; + private _initialized: boolean; + + public static createAsset(name: string, source: string, texture: Texture, x: number, y: number, flipH: boolean = false, flipV: boolean = false, usesPalette: boolean = false): GraphicAsset + { + const graphicAsset = (GraphicAsset.GRAPHIC_POOL.length ? GraphicAsset.GRAPHIC_POOL.pop() : new GraphicAsset()); + + graphicAsset._name = name; + graphicAsset._source = source || null; + + if(texture) + { + graphicAsset._texture = texture; + graphicAsset._initialized = false; + } + else + { + graphicAsset._texture = null; + graphicAsset._initialized = true; + } + + graphicAsset._usesPalette = usesPalette; + graphicAsset._x = x; + graphicAsset._y = y; + graphicAsset._flipH = flipH; + graphicAsset._flipV = flipV; + graphicAsset._rectangle = null; + + return graphicAsset; + } + + public recycle(): void + { + this._texture = null; + + GraphicAsset.GRAPHIC_POOL.push(this); + } + + private initialize(): void + { + if(this._initialized || !this._texture) return; + + this._width = this._texture.width; + this._height = this._texture.height; + + this._initialized = true; + } + + public get name(): string + { + return this._name; + } + + public get source(): string + { + return this._source; + } + + public get texture(): Texture + { + return this._texture; + } + + public get usesPalette(): boolean + { + return this._usesPalette; + } + + public get x(): number + { + return this._x; + } + + public get y(): number + { + return this._y; + } + + public get width(): number + { + this.initialize(); + + return this._width; + } + + public get height(): number + { + this.initialize(); + + return this._height; + } + + public get offsetX(): number + { + if(!this._flipH) return this._x; + + return (-(this._x)); + } + + public get offsetY(): number + { + if(!this._flipV) return this._y; + + return (-(this._y)); + } + + public get flipH(): boolean + { + return this._flipH; + } + + public get flipV(): boolean + { + return this._flipV; + } + + public get rectangle(): Rectangle + { + if(!this._rectangle) this._rectangle = new Rectangle(0, 0, this.width, this.height); + + return this._rectangle; + } +} \ No newline at end of file diff --git a/src/room/object/visualization/utils/GraphicAssetCollection.ts b/src/room/object/visualization/utils/GraphicAssetCollection.ts new file mode 100644 index 00000000..0b582a0b --- /dev/null +++ b/src/room/object/visualization/utils/GraphicAssetCollection.ts @@ -0,0 +1,372 @@ +import { Spritesheet, Texture } from 'pixi.js'; +import { AssetManager } from '../../../../core/asset/AssetManager'; +import { IAsset, IAssetData, IAssetPalette } from '../../../../core/asset/interfaces'; +import { Nitro } from '../../../../nitro/Nitro'; +import { GraphicAsset } from './GraphicAsset'; +import { GraphicAssetPalette } from './GraphicAssetPalette'; +import { IGraphicAsset } from './IGraphicAsset'; +import { IGraphicAssetCollection } from './IGraphicAssetCollection'; + +export class GraphicAssetCollection implements IGraphicAssetCollection +{ + private static PALETTE_ASSET_DISPOSE_THRESHOLD: number = 10; + + private _referenceCount: number; + private _referenceTimestamp: number; + + private _name: string; + private _data: IAssetData; + private _textures: Map; + private _assets: Map; + private _palettes: Map; + private _paletteAssetNames: string[]; + + constructor(data: IAssetData, spritesheet: Spritesheet) + { + if(!data) throw new Error('invalid_collection'); + + this._name = data.name; + this._data = data; + this._textures = new Map(); + this._assets = new Map(); + this._palettes = new Map(); + this._paletteAssetNames = []; + + if(spritesheet) this.addLibraryAsset(spritesheet.textures); + + this.define(data); + } + + public dispose(): void + { + if(this._palettes) + { + for(const palette of this._palettes.values()) palette.dispose(); + + this._palettes.clear(); + } + + if(this._paletteAssetNames) + { + this.disposePaletteAssets(); + + this._paletteAssetNames = null; + } + + if(this._assets) + { + for(const asset of this._assets.values()) asset.recycle(); + + this._assets.clear(); + } + } + + public addReference(): void + { + this._referenceCount++; + this._referenceTimestamp = Nitro.instance.time; + } + + public removeReference(): void + { + this._referenceCount--; + + if(this._referenceCount <= 0) + { + this._referenceCount = 0; + this._referenceTimestamp = Nitro.instance.time; + + this.disposePaletteAssets(false); + } + } + + public define(data: IAssetData): void + { + const assets = data.assets; + const palettes = data.palettes; + + if(assets) this.defineAssets(assets); + + if(palettes) this.definePalettes(palettes); + } + + private defineAssets(assets: { [index: string]: IAsset }): void + { + if(!assets) return; + + for(const name in assets) + { + const asset = assets[name]; + + if(!asset) continue; + + const x = (-(asset.x) || 0); + const y = (-(asset.y) || 0); + let flipH = false; + const flipV = false; + const usesPalette = (asset.usesPalette || false); + let source = (asset.source || ''); + + if(asset.flipH && source.length) flipH = true; + + // if(asset.flipV && source.length) flipV = true; + + if(!source.length) source = name; + + const texture = this.getLibraryAsset(source); + + if(!texture) continue; + + let didAddAsset = this.createAsset(name, source, texture, flipH, flipV, x, y, usesPalette); + + if(!didAddAsset) + { + const existingAsset = this.getAsset(name); + + if(existingAsset && (existingAsset.name !== existingAsset.source)) + { + didAddAsset = this.replaceAsset(name, source, texture, flipH, flipV, x, y, usesPalette); + } + } + } + } + + private definePalettes(palettes: { [index: string]: IAssetPalette }): void + { + if(!palettes) return; + + for(const name in palettes) + { + const palette = palettes[name]; + + if(!palette) continue; + + const id = palette.id.toString(); + + if(this._palettes.get(id)) continue; + + let colorOne = 0xFFFFFF; + let colorTwo = 0xFFFFFF; + + let color = palette.color1; + + if(color && color.length > 0) colorOne = parseInt(color, 16); + + color = palette.color2; + + if(color && color.length > 0) colorTwo = parseInt(color, 16); + + this._palettes.set(id, new GraphicAssetPalette(palette.rgb, colorOne, colorTwo)); + } + } + + private createAsset(name: string, source: string, texture: Texture, flipH: boolean, flipV: boolean, x: number, y: number, usesPalette: boolean): boolean + { + if(this._assets.get(name)) return false; + + const graphicAsset = GraphicAsset.createAsset(name, source, texture, x, y, flipH, flipV, usesPalette); + + this._assets.set(name, graphicAsset); + + return true; + } + + private replaceAsset(name: string, source: string, texture: Texture, flipH: boolean, flipV: boolean, x: number, y: number, usesPalette: boolean): boolean + { + const existing = this._assets.get(name); + + if(existing) + { + this._assets.delete(name); + + existing.recycle(); + } + + return this.createAsset(name, source, texture, flipH, flipV, x, y, usesPalette); + } + + public getAsset(name: string): IGraphicAsset + { + if(!name) return null; + + const existing = this._assets.get(name); + + if(!existing) return null; + + return existing; + } + + public getAssetWithPalette(name: string, paletteName: string): IGraphicAsset + { + const saveName = (name + '@' + paletteName); + + let asset = this.getAsset(saveName); + + if(!asset) + { + asset = this.getAsset(name); + + if(!asset || !asset.usesPalette) return asset; + + const palette = this.getPalette(paletteName); + + if(palette) + { + const texture = palette.applyPalette(asset.texture); + + if(texture) + { + this._paletteAssetNames.push(saveName); + + this.createAsset(saveName, (asset.source + '@' + paletteName), texture, asset.flipH, asset.flipV, asset.x, asset.y, false); + + asset = this.getAsset(saveName); + } + } + } + + return asset; + } + + public getPaletteNames(): string[] + { + return Array.from(this._palettes.keys()); + } + + public getPaletteColors(paletteName: string): number[] + { + const palette = this.getPalette(paletteName); + + if(palette) return [ palette.primaryColor, palette.secondaryColor ]; + + return null; + } + + public getPalette(name: string): GraphicAssetPalette + { + if(!name) return null; + + const existing = this._palettes.get(name); + + if(!existing) return null; + + return existing; + } + + public addAsset(name: string, texture: Texture, override: boolean, x: number = 0, y: number = 0, flipH: boolean = false, flipV: boolean = false): boolean + { + if(!name || !texture) return false; + + const existingTexture = this.getLibraryAsset(name); + + if(!existingTexture) + { + this._textures.set(name, texture); + + return this.createAsset(name, name, texture, flipH, flipV, x, y, false); + } + + if(override) + { + existingTexture.baseTexture = texture.baseTexture; + existingTexture.frame = texture.frame; + existingTexture.trim = texture.trim; + + existingTexture.updateUvs(); + + return true; + } + + return false; + } + + public disposeAsset(name: string): void + { + const existing = this._assets.get(name); + + if(!existing) return; + + this._assets.delete(name); + + const texture = this.getLibraryAsset(existing.source); + + if(texture) + { + this._textures.delete(existing.source); + + texture.destroy(true); + } + + existing.recycle(); + } + + public getLibraryAsset(name: string): Texture + { + if(!name) return null; + + name = this._name + '_' + name; + + const texture = this._textures.get(name); + + if(!texture) return null; + + return texture; + } + + private addLibraryAsset(textures: Texture[]): void + { + if(!textures) return; + + for(const name in textures) + { + const texture = textures[name]; + + if(!texture) continue; + + this._textures.set(AssetManager.removeFileExtension(name), texture); + } + } + + private disposePaletteAssets(disposeAll: boolean = true): void + { + if(this._paletteAssetNames) + { + if(disposeAll || (this._paletteAssetNames.length > GraphicAssetCollection.PALETTE_ASSET_DISPOSE_THRESHOLD)) + { + for(const name of this._paletteAssetNames) this.disposeAsset(name); + + this._paletteAssetNames = []; + } + } + } + + public get referenceCount(): number + { + return this._referenceCount; + } + + public get referenceTimestamp(): number + { + return this._referenceTimestamp; + } + + public get name(): string + { + return this._name; + } + + public get data(): IAssetData + { + return this._data; + } + + public get textures(): Map + { + return this._textures; + } + + public get assets(): Map + { + return this._assets; + } +} diff --git a/src/room/object/visualization/utils/GraphicAssetPalette.ts b/src/room/object/visualization/utils/GraphicAssetPalette.ts new file mode 100644 index 00000000..101d3001 --- /dev/null +++ b/src/room/object/visualization/utils/GraphicAssetPalette.ts @@ -0,0 +1,58 @@ +import { Sprite, Texture } from 'pixi.js'; +import { Nitro } from '../../../../nitro/Nitro'; + +export class GraphicAssetPalette +{ + private _palette: [ number, number, number ][]; + private _primaryColor: number; + private _secondaryColor: number; + + constructor(palette: [ number, number, number ][], primaryColor: number, secondaryColor: number) + { + this._palette = palette; + + while(this._palette.length < 256) this._palette.push([ 0, 0, 0 ]); + + this._primaryColor = primaryColor; + this._secondaryColor = secondaryColor; + } + + public dispose(): void + { + + } + + public applyPalette(texture: Texture): Texture + { + const sprite = Sprite.from(texture); + const textureCanvas = Nitro.instance.renderer.extract.canvas(sprite); + const textureCtx = textureCanvas.getContext('2d'); + const textureImageData = textureCtx.getImageData(0, 0, textureCanvas.width, textureCanvas.height); + const data = textureImageData.data; + + for(let i = 0; i < data.length; i += 4) + { + let paletteColor = this._palette[data[ i + 1 ]]; + + if(paletteColor === undefined) paletteColor = [ 0, 0, 0 ]; + + data[ i ] = paletteColor[0]; + data[ i + 1 ] = paletteColor[1]; + data[ i + 2 ] = paletteColor[2]; + } + + textureCtx.putImageData(textureImageData, 0, 0); + + return Texture.from(textureCanvas); + } + + public get primaryColor(): number + { + return this._primaryColor; + } + + public get secondaryColor(): number + { + return this._secondaryColor; + } +} diff --git a/src/room/object/visualization/utils/IGraphicAsset.ts b/src/room/object/visualization/utils/IGraphicAsset.ts new file mode 100644 index 00000000..ccb372a8 --- /dev/null +++ b/src/room/object/visualization/utils/IGraphicAsset.ts @@ -0,0 +1,18 @@ +import { Rectangle, Texture } from 'pixi.js'; + +export interface IGraphicAsset +{ + name: string; + source: string; + texture: Texture; + usesPalette: boolean; + x: number; + y: number; + width: number; + height: number; + offsetX: number; + offsetY: number; + flipH: boolean; + flipV: boolean; + rectangle: Rectangle; +} \ No newline at end of file diff --git a/src/room/object/visualization/utils/IGraphicAssetCollection.ts b/src/room/object/visualization/utils/IGraphicAssetCollection.ts new file mode 100644 index 00000000..1d4b0eaf --- /dev/null +++ b/src/room/object/visualization/utils/IGraphicAssetCollection.ts @@ -0,0 +1,23 @@ +import { Texture } from 'pixi.js'; +import { IAssetData } from '../../../../core/asset/interfaces'; +import { GraphicAssetPalette } from './GraphicAssetPalette'; +import { IGraphicAsset } from './IGraphicAsset'; + +export interface IGraphicAssetCollection +{ + dispose(): void; + addReference(): void; + removeReference(): void; + define(data: IAssetData): void; + getAsset(name: string): IGraphicAsset; + getAssetWithPalette(name: string, paletteName: string): IGraphicAsset; + getPaletteNames(): string[]; + getPaletteColors(paletteName: string): number[]; + getPalette(name: string): GraphicAssetPalette; + addAsset(name: string, texture: Texture, override: boolean, x?: number, y?: number, flipH?: boolean, flipV?: boolean): boolean; + disposeAsset(name: string): void; + referenceCount: number; + referenceTimestamp: number; + name: string; + data: IAssetData; +} \ No newline at end of file diff --git a/src/room/renderer/IRoomCanvasMouseListener.ts b/src/room/renderer/IRoomCanvasMouseListener.ts new file mode 100644 index 00000000..e12f2002 --- /dev/null +++ b/src/room/renderer/IRoomCanvasMouseListener.ts @@ -0,0 +1,8 @@ +import { RoomSpriteMouseEvent } from '../events/RoomSpriteMouseEvent'; +import { IRoomObject } from '../object/IRoomObject'; +import { IRoomGeometry } from '../utils/IRoomGeometry'; + +export interface IRoomCanvasMouseListener +{ + _Str_20330(event: RoomSpriteMouseEvent, object: IRoomObject, geometry: IRoomGeometry): void +} \ No newline at end of file diff --git a/src/room/renderer/IRoomRenderer.ts b/src/room/renderer/IRoomRenderer.ts new file mode 100644 index 00000000..44779178 --- /dev/null +++ b/src/room/renderer/IRoomRenderer.ts @@ -0,0 +1,9 @@ +import { IRoomRendererBase } from './IRoomRendererBase'; +import { IRoomRenderingCanvas } from './IRoomRenderingCanvas'; + +export interface IRoomRenderer extends IRoomRendererBase +{ + getCanvas(id: number): IRoomRenderingCanvas; + createCanvas(id: number, width: number, height: number, scale: number): IRoomRenderingCanvas; + roomObjectVariableAccurateZ: string; +} \ No newline at end of file diff --git a/src/room/renderer/IRoomRendererBase.ts b/src/room/renderer/IRoomRendererBase.ts new file mode 100644 index 00000000..ca6d3685 --- /dev/null +++ b/src/room/renderer/IRoomRendererBase.ts @@ -0,0 +1,10 @@ +import { IRoomObject } from '../object/IRoomObject'; + +export interface IRoomRendererBase +{ + addObject(object: IRoomObject): void; + removeObject(object: IRoomObject): void; + dispose(): void; + reset(): void; + update(time: number, update?: boolean): void; +} \ No newline at end of file diff --git a/src/room/renderer/IRoomRendererFactory.ts b/src/room/renderer/IRoomRendererFactory.ts new file mode 100644 index 00000000..1456669d --- /dev/null +++ b/src/room/renderer/IRoomRendererFactory.ts @@ -0,0 +1,6 @@ +import { IRoomRenderer } from './IRoomRenderer'; + +export interface IRoomRendererFactory +{ + createRenderer(): IRoomRenderer; +} \ No newline at end of file diff --git a/src/room/renderer/IRoomRenderingCanvas.ts b/src/room/renderer/IRoomRenderingCanvas.ts new file mode 100644 index 00000000..fbc5a729 --- /dev/null +++ b/src/room/renderer/IRoomRenderingCanvas.ts @@ -0,0 +1,33 @@ +import { DisplayObject, Point, RenderTexture } from 'pixi.js'; +import { RoomObjectSpriteData } from '../data/RoomObjectSpriteData'; +import { IRoomGeometry } from '../utils/IRoomGeometry'; +import { IRoomCanvasMouseListener } from './IRoomCanvasMouseListener'; +import { SortableSprite } from './utils/SortableSprite'; + +export interface IRoomRenderingCanvas +{ + dispose(): void; + initialize(width: number, height: number): void; + setMask(flag: boolean): void; + setScale(scale: number, point?: Point, offsetPoint?: Point, override?: boolean, asDelta?: boolean): void; + render(time: number, update?: boolean): void; + update(): void; + setMouseListener(listener: IRoomCanvasMouseListener): void; + _Str_20787(): void; + _Str_22174(): void; + _Str_14588(): SortableSprite[]; + _Str_21232(k: number, _arg_2: number, _arg_3: string, _arg_4: boolean, _arg_5: boolean, _arg_6: boolean, _arg_7: boolean): boolean; + getSortableSpriteList(): RoomObjectSpriteData[]; + getDisplayAsTexture(): RenderTexture; + id: number; + geometry: IRoomGeometry; + master: DisplayObject; + display: DisplayObject; + screenOffsetX: number; + screenOffsetY: number; + scale: number; + width: number; + height: number; + restrictsScaling: boolean; + canvasUpdated: boolean; +} \ No newline at end of file diff --git a/src/room/renderer/IRoomSpriteCanvasContainer.ts b/src/room/renderer/IRoomSpriteCanvasContainer.ts new file mode 100644 index 00000000..f144b68c --- /dev/null +++ b/src/room/renderer/IRoomSpriteCanvasContainer.ts @@ -0,0 +1,8 @@ +import { IRoomObject } from '../object/IRoomObject'; + +export interface IRoomSpriteCanvasContainer +{ + getRoomObject(instanceId: number): IRoomObject; + objects: Map; + roomObjectVariableAccurateZ: string; +} \ No newline at end of file diff --git a/src/room/renderer/RoomRenderer.ts b/src/room/renderer/RoomRenderer.ts new file mode 100644 index 00000000..6282b70d --- /dev/null +++ b/src/room/renderer/RoomRenderer.ts @@ -0,0 +1,172 @@ +import { IRoomObject } from '../object/IRoomObject'; +import { IRoomRenderer } from './IRoomRenderer'; +import { IRoomRenderingCanvas } from './IRoomRenderingCanvas'; +import { IRoomSpriteCanvasContainer } from './IRoomSpriteCanvasContainer'; +import { RoomSpriteCanvas } from './RoomSpriteCanvas'; + +export class RoomRenderer implements IRoomRenderer, IRoomSpriteCanvasContainer +{ + private _objects: Map; + private _canvases: Map; + + private _disposed: boolean; + private _roomObjectVariableAccurateZ: string; + + constructor() + { + this._objects = new Map(); + this._canvases = new Map(); + + this._disposed = false; + this._roomObjectVariableAccurateZ = null; + } + + public dispose(): void + { + if(this._disposed) return; + + if(this._canvases) + { + for(const [ key, canvas ] of this._canvases.entries()) + { + this._canvases.delete(key); + + if(!canvas) continue; + + canvas.dispose(); + } + + this._canvases = null; + } + + if(this._objects) + { + this._objects = null; + } + + this._disposed = true; + } + + public reset(): void + { + this._objects.clear(); + } + + public getInstanceId(object: IRoomObject): number + { + if(!object) return -1; + + return object.instanceId; + } + + public getRoomObject(instanceId: number): IRoomObject + { + return this._objects.get(instanceId); + } + + public addObject(object: IRoomObject): void + { + if(!object) return; + + this._objects.set(this.getInstanceId(object), object); + } + + public removeObject(object: IRoomObject): void + { + const instanceId = this.getInstanceId(object); + + this._objects.delete(instanceId); + + for(const canvas of this._canvases.values()) + { + if(!canvas) continue; + + const spriteCanvas = canvas as RoomSpriteCanvas; + + spriteCanvas.removeFromCache(instanceId.toString()); + } + } + + public render(time: number, update: boolean = false): void + { + if(!this._canvases || !this._canvases.size) return; + + for(const canvas of this._canvases.values()) canvas && canvas.render(time, update); + } + + public update(time: number, update: boolean = false): void + { + if(!this._canvases || !this._canvases.size) return; + + this.render(time, update); + + for(const canvas of this._canvases.values()) canvas && canvas.update(); + } + + public getCanvas(id: number): IRoomRenderingCanvas + { + const existing = this._canvases.get(id); + + if(!existing) return; + + return existing; + } + + public createCanvas(id: number, width: number, height: number, scale: number): IRoomRenderingCanvas + { + const existing = this._canvases.get(id) as IRoomRenderingCanvas; + + if(existing) + { + existing.initialize(width, height); + + if(existing.geometry) existing.geometry.scale = scale; + + return existing; + } + + const canvas = this.createSpriteCanvas(id, width, height, scale); + + if(!canvas) return; + + this._canvases.set(id, canvas); + + return canvas; + } + + private createSpriteCanvas(id: number, width: number, height: number, scale: number): IRoomRenderingCanvas + { + return new RoomSpriteCanvas(this, id, width, height, scale); + } + + public removeCanvas(id: number): void + { + const existing = this._canvases.get(id); + + if(!existing) return; + + this._canvases.delete(id); + + existing.dispose(); + } + + public get objects(): Map + { + return this._objects; + } + + public get disposed(): boolean + { + return this._disposed; + } + + public get roomObjectVariableAccurateZ(): string + { + return this._roomObjectVariableAccurateZ; + } + + public set roomObjectVariableAccurateZ(z: string) + { + this._roomObjectVariableAccurateZ = z; + } +} \ No newline at end of file diff --git a/src/room/renderer/RoomRendererFactory.ts b/src/room/renderer/RoomRendererFactory.ts new file mode 100644 index 00000000..34eb2a67 --- /dev/null +++ b/src/room/renderer/RoomRendererFactory.ts @@ -0,0 +1,11 @@ +import { IRoomRenderer } from './IRoomRenderer'; +import { IRoomRendererFactory } from './IRoomRendererFactory'; +import { RoomRenderer } from './RoomRenderer'; + +export class RoomRendererFactory implements IRoomRendererFactory +{ + public createRenderer(): IRoomRenderer + { + return new RoomRenderer(); + } +} \ No newline at end of file diff --git a/src/room/renderer/RoomSpriteCanvas.ts b/src/room/renderer/RoomSpriteCanvas.ts new file mode 100644 index 00000000..418c58a6 --- /dev/null +++ b/src/room/renderer/RoomSpriteCanvas.ts @@ -0,0 +1,1083 @@ +import { Container, DisplayObject, Graphics, Matrix, Point, Rectangle, RenderTexture, Sprite } from 'pixi.js'; +import { Nitro } from '../../nitro/Nitro'; +import { MouseEventType } from '../../nitro/ui/MouseEventType'; +import { RoomObjectSpriteData } from '../data/RoomObjectSpriteData'; +import { RoomSpriteMouseEvent } from '../events/RoomSpriteMouseEvent'; +import { RoomObjectSpriteType } from '../object/enum/RoomObjectSpriteType'; +import { IRoomObject } from '../object/IRoomObject'; +import { IRoomObjectSprite } from '../object/visualization/IRoomObjectSprite'; +import { IRoomObjectSpriteVisualization } from '../object/visualization/IRoomObjectSpriteVisualization'; +import { IRoomGeometry } from '../utils/IRoomGeometry'; +import { RoomEnterEffect } from '../utils/RoomEnterEffect'; +import { RoomGeometry } from '../utils/RoomGeometry'; +import { Vector3d } from '../utils/Vector3d'; +import { RoomObjectCache } from './cache/RoomObjectCache'; +import { RoomObjectCacheItem } from './cache/RoomObjectCacheItem'; +import { IRoomCanvasMouseListener } from './IRoomCanvasMouseListener'; +import { IRoomRenderingCanvas } from './IRoomRenderingCanvas'; +import { IRoomSpriteCanvasContainer } from './IRoomSpriteCanvasContainer'; +import { ExtendedSprite } from './utils/ExtendedSprite'; +import { ObjectMouseData } from './utils/ObjectMouseData'; +import { SortableSprite } from './utils/SortableSprite'; + +export class RoomSpriteCanvas implements IRoomRenderingCanvas +{ + private _id: number; + private _container: IRoomSpriteCanvasContainer; + + private _geometry: RoomGeometry; + private _renderTimestamp: number; + + private _master: Sprite; + private _display: Container; + private _mask: Graphics; + + private _sortableSprites: SortableSprite[]; + private _spriteCount: number; + private _activeSpriteCount: number; + private _spritePool: ExtendedSprite[]; + private _skipObjectUpdate: boolean; + private _runningSlow: boolean; + + private _width: number; + private _height: number; + private _renderedWidth: number; + private _renderedHeight: number; + private _screenOffsetX: number; + private _screenOffsetY: number; + private _mouseLocation: Point; + private _mouseOldX: number; + private _mouseOldY: number; + private _mouseCheckCount: number; + private _mouseSpriteWasHit: boolean; + private _mouseActiveObjects: Map; + private _eventCache: Map; + private _eventId: number; + private _scale: number; + + private _restrictsScaling: boolean; + private _noSpriteVisibilityChecking: boolean; + private _usesExclusionRectangles: boolean; + private _usesMask: boolean; + private _canvasUpdated: boolean; + + private _objectCache: RoomObjectCache; + + private _mouseListener: IRoomCanvasMouseListener; + + constructor(container: IRoomSpriteCanvasContainer, id: number, width: number, height: number, scale: number) + { + this._id = id; + this._container = container; + + this._geometry = new RoomGeometry(scale, new Vector3d(-135, 30, 0), new Vector3d(11, 11, 5), new Vector3d(-135, 0.5, 0)); + this._renderTimestamp = 0; + + this._master = null; + this._display = null; + this._mask = null; + + this._sortableSprites = []; + this._spriteCount = 0; + this._activeSpriteCount = 0; + this._spritePool = []; + this._skipObjectUpdate = false; + this._runningSlow = false; + + this._width = 0; + this._height = 0; + this._renderedWidth = 0; + this._renderedHeight = 0; + this._screenOffsetX = 0; + this._screenOffsetY = 0; + this._mouseLocation = new Point; + this._mouseOldX = 0; + this._mouseOldY = 0; + this._mouseCheckCount = 0; + this._mouseSpriteWasHit = false; + this._mouseActiveObjects = new Map(); + this._eventCache = new Map(); + this._eventId = 0; + this._scale = 1; + + this._restrictsScaling = false; + this._noSpriteVisibilityChecking = false; + this._usesExclusionRectangles = false; + this._usesMask = true; + this._canvasUpdated = false; + + this._objectCache = new RoomObjectCache(this._container.roomObjectVariableAccurateZ); + + this._mouseListener = null; + + this.setupCanvas(); + this.initialize(width, height); + } + + private setupCanvas(): void + { + if(!this._master) + { + this._master = new Sprite(); + + this._master.interactiveChildren = false; + } + + if(!this._display) + { + const display = new Container(); + + display.name = 'canvas'; + + this._master.addChild(display); + + this._display = display; + } + } + + public dispose(): void + { + this._Str_20677(0, true); + + if(this._geometry) + { + this._geometry.dispose(); + + this._geometry = null; + } + + if(this._mask) this._mask = null; + + if(this._objectCache) + { + this._objectCache.dispose(); + + this._objectCache = null; + } + + if(this._master) + { + while(this._master.children.length) + { + const child = this._master.removeChildAt(0); + + child.destroy(); + } + + if(this._master.parent) this._master.parent.removeChild(this._master); + + this._master.destroy(); + + this._master = null; + } + + this._display = null; + this._sortableSprites = []; + + if(this._mouseActiveObjects) + { + this._mouseActiveObjects.clear(); + + this._mouseActiveObjects = null; + } + + if(this._spritePool) + { + for(const sprite of this._spritePool) + { + this._Str_21974(sprite, true); + } + + this._spritePool = []; + } + + if(this._eventCache) + { + this._eventCache.clear(); + + this._eventCache = null; + } + + this._mouseListener = null; + } + + public initialize(width: number, height: number): void + { + width = width < 1 ? 1 : width; + height = height < 1 ? 1 : height; + + if(this._usesMask) + { + if(!this._mask) + { + this._mask = new Graphics() + .beginFill(0xFF0000) + .drawRect(0, 0, width, height) + .endFill(); + + this._mask.name = 'mask'; + + if(this._master) + { + this._master.addChild(this._mask); + + if(this._display) this._display.mask = this._mask; + } + } + else + { + this._mask + .clear() + .beginFill(0xFF0000) + .drawRect(0, 0, width, height) + .endFill(); + } + } + + if(this._master) + { + if(this._master.hitArea) + { + const hitArea = (this._master.hitArea as Rectangle); + + hitArea.width = width; + hitArea.height = height; + } + else + { + this._master.hitArea = new Rectangle(0, 0, width, height); + } + + if(this._master.filterArea) + { + const filterArea = this._master.filterArea; + + filterArea.width = width; + filterArea.height = height; + } + else + { + this._master.filterArea = new Rectangle(0, 0, width, height); + } + } + + this._width = width; + this._height = height; + } + + public setMask(flag: boolean): void + { + if(flag && !this._usesMask) + { + this._usesMask = true; + + if(this._mask && (this._mask.parent !== this._master)) + { + this._master.addChild(this._mask); + + this._display.mask = this._mask; + } + } + + else if(!flag && this._usesMask) + { + this._usesMask = false; + + if(this._mask && (this._mask.parent === this._master)) + { + this._master.removeChild(this._mask); + + this._display.mask = null; + } + } + } + + public setScale(scale: number, point: Point = null, offsetPoint: Point = null, override: boolean = false, asDelta: boolean = false): void + { + if(!this._master || !this._display) return; + + if(this._restrictsScaling && !override) return; + + if(!point) point = new Point((this._width / 2), (this._height / 2)); + + if(!offsetPoint) offsetPoint = point; + + point = this._display.toLocal(point); + + if(asDelta) + { + this._scale *= scale; + } + else + { + this._scale = scale; + } + + this.screenOffsetX = (offsetPoint.x - (point.x * this._scale)); + this.screenOffsetY = (offsetPoint.y - (point.y * this._scale)); + } + + public render(time: number, update: boolean = false): void + { + this._canvasUpdated = false; + + if(time === -1) time = (this._renderTimestamp + 1); + + if(!this._container || !this._geometry) return; + + if(time === this._renderTimestamp) return; + + if((this._width !== this._renderedWidth) || (this._height !== this._renderedHeight)) update = true; + + if((this._display.x !== this._screenOffsetX) || (this._display.y !== this._screenOffsetY)) + { + this._display.x = this._screenOffsetX; + this._display.y = this._screenOffsetY; + + update = true; + } + + if(this._display.scale.x !== this._scale) + { + this._display.scale.set(this._scale); + + update = true; + } + + let spriteCount = 0; + + const objects = this._container.objects; + + if(objects.size) + { + for(const object of objects.values()) + { + if(!object) continue; + + spriteCount = (spriteCount + this.renderObject(object, object.instanceId.toString(), time, update, spriteCount)); + } + } + + this._sortableSprites.sort((a, b) => + { + return b.z - a.z; + }); + + if(spriteCount < this._sortableSprites.length) + { + this._sortableSprites.splice(spriteCount); + } + + let iterator = 0; + + while(iterator < spriteCount) + { + const sprite = this._sortableSprites[iterator]; + + if(sprite && sprite.sprite) this.renderSprite(iterator, sprite); + + iterator++; + } + + this._Str_20677(spriteCount); + + if(update) this._canvasUpdated = true; + + this._renderTimestamp = time; + this._renderedWidth = this._width; + this._renderedHeight = this._height; + } + + public _Str_20787(): void + { + this._noSpriteVisibilityChecking = true; + + this.render(-1, true); + } + + public _Str_22174(): void + { + this._noSpriteVisibilityChecking = false; + } + + public getSortableSpriteList(): RoomObjectSpriteData[] + { + return this._objectCache.getSortableSpriteList(); + } + + public _Str_14588(): SortableSprite[] + { + return this._objectCache.getPlaneSortableSprites(); + } + + public removeFromCache(identifier: string): void + { + this._objectCache.removeObjectCache(identifier); + } + + private renderObject(object: IRoomObject, identifier: string, time: number, update: boolean, count: number): number + { + if(!object) return 0; + + const visualization = object.visualization as IRoomObjectSpriteVisualization; + + if(!visualization) + { + this.removeFromCache(identifier); + + return 0; + } + + const cache = this.getCacheItem(identifier); + cache._Str_1577 = object.instanceId; + + const locationCache = cache.location; + const sortableCache = cache.sprites; + + const vector = locationCache.updateLocation(object, this._geometry); + + if(!vector) + { + this.removeFromCache(identifier); + + return 0; + } + + visualization.update(this._geometry, time, (!sortableCache.isEmpty || update), (this._skipObjectUpdate && this._runningSlow)); + + if(locationCache.locationChanged) update = true; + + if(!sortableCache._Str_17574(visualization.instanceId, visualization.updateSpriteCounter) && !update) + { + return sortableCache._Str_3008; + } + + let x = vector.x; + let y = vector.y; + let z = vector.z; + + if(x > 0) z = (z + (x * 1.2E-7)); + else z = (z + (-(x) * 1.2E-7)); + + x = (x + Math.trunc(this._width / 2)); + y = (y + Math.trunc(this._height / 2)); + + let spriteCount = 0; + + for(const sprite of visualization.sprites.values()) + { + if(!sprite || !sprite.visible) continue; + + const texture = sprite.texture; + const baseTexture = texture && texture.baseTexture; + + if(!texture || !baseTexture) continue; + + const spriteX = ((x + sprite.offsetX) + this._screenOffsetX); + const spriteY = ((y + sprite.offsetY) + this._screenOffsetY); + + if(sprite.flipH) + { + const checkX = ((x + (-(texture.width + (-(sprite.offsetX))))) + this._screenOffsetX); + + if(!this.isSpriteVisible(checkX, spriteY, texture.width, texture.height)) continue; + } + + else if(sprite.flipV) + { + const checkY = ((y + (-(texture.height + (-(sprite.offsetY))))) + this._screenOffsetY); + + if(!this.isSpriteVisible(spriteX, checkY, texture.width, texture.height)) continue; + } + + else + { + if(!this.isSpriteVisible(spriteX, spriteY, texture.width, texture.height)) continue; + } + + let sortableSprite = sortableCache._Str_2505(spriteCount); + + if(!sortableSprite) + { + sortableSprite = new SortableSprite(); + + sortableCache._Str_12937(sortableSprite); + + this._sortableSprites.push(sortableSprite); + + sortableSprite.name = identifier; + } + + sortableSprite.sprite = sprite; + + if((sprite.spriteType === RoomObjectSpriteType._Str_11629) || (sprite.spriteType === RoomObjectSpriteType._Str_10494)) + { + sortableSprite.sprite._Str_3582 = 'avatar_' + object.id; + } + + sortableSprite.x = (spriteX - this._screenOffsetX); + sortableSprite.y = (spriteY - this._screenOffsetY); + sortableSprite.z = ((z + sprite.relativeDepth) + (3.7E-11 * count)); + + spriteCount++; + count++; + } + + sortableCache._Str_20276(spriteCount); + + this._canvasUpdated = true; + + return spriteCount; + } + + private getExtendedSprite(index: number): ExtendedSprite + { + if((index < 0) || (index >= this._spriteCount)) return null; + + const sprite = this._display.getChildAt(index); + + if(!sprite) return null; + + return sprite as ExtendedSprite; + } + + protected getExtendedSpriteIdentifier(sprite: ExtendedSprite): string + { + if(!sprite) return ''; + + return sprite.name; + } + + private renderSprite(index: number, sprite: SortableSprite): boolean + { + if(index >= this._spriteCount) + { + this.createAndAddSprite(sprite); + + return true; + } + + if(!sprite) return false; + + const objectSprite = sprite.sprite; + const extendedSprite = this.getExtendedSprite(index); + + if(!objectSprite || !extendedSprite) return false; + + if(extendedSprite._Str_4593 !== objectSprite._Str_4593) + { + if(extendedSprite._Str_4593 && !objectSprite._Str_4593) + { + this._display.removeChildAt(index); + + this._spritePool.push(extendedSprite); + + return this.renderSprite(index, sprite); + } + + this.createAndAddSprite(sprite, index); + + return true; + } + + if(extendedSprite.needsUpdate(objectSprite.id, objectSprite.updateCounter) || RoomEnterEffect.isVisualizationOn()) + { + extendedSprite.tag = objectSprite.tag; + extendedSprite.alphaTolerance = objectSprite.alphaTolerance; + extendedSprite.name = sprite.name; + extendedSprite._Str_4593 = objectSprite._Str_4593; + extendedSprite.clickHandling = objectSprite.clickHandling; + extendedSprite.filters = objectSprite.filters; + + const alpha = (objectSprite.alpha / 255); + + if(extendedSprite.alpha !== alpha) extendedSprite.alpha = alpha; + + if(extendedSprite.tint !== objectSprite.color) extendedSprite.tint = objectSprite.color; + + if(extendedSprite.blendMode !== objectSprite.blendMode) extendedSprite.blendMode = objectSprite.blendMode; + + if(extendedSprite.texture !== objectSprite.texture) extendedSprite.setTexture(objectSprite.texture); + + if(objectSprite.updateContainer) + { + const length = extendedSprite.children.length; + + if(length === 1) extendedSprite.removeChildAt(0); + + extendedSprite.addChild(objectSprite.container); + + objectSprite.updateContainer = false; + } + + if(objectSprite.flipH) + { + if(extendedSprite.scale.x !== -1) extendedSprite.scale.x = -1; + } + else + { + if(extendedSprite.scale.x !== 1) extendedSprite.scale.x = 1; + } + + if(objectSprite.flipV) + { + if(extendedSprite.scale.y !== -1) extendedSprite.scale.y = -1; + } + else + { + if(extendedSprite.scale.y !== 1) extendedSprite.scale.y = 1; + } + + this._Str_21914(extendedSprite, objectSprite); + } + + if(extendedSprite.x !== sprite.x) extendedSprite.x = sprite.x; + if(extendedSprite.y !== sprite.y) extendedSprite.y = sprite.y; + + extendedSprite.offsetX = objectSprite.offsetX; + extendedSprite.offsetY = objectSprite.offsetY; + + return true; + } + + private createAndAddSprite(sortableSprite: SortableSprite, index: number = -1): void + { + const sprite = sortableSprite.sprite; + + if(!sprite) return; + + let extendedSprite: ExtendedSprite = null; + + if(this._spritePool.length > 0) extendedSprite = this._spritePool.pop(); + + if(!extendedSprite) extendedSprite = new ExtendedSprite(); + + if(extendedSprite.children.length) extendedSprite.removeChildren(); + + extendedSprite.tag = sprite.tag; + extendedSprite.alphaTolerance = sprite.alphaTolerance; + extendedSprite.alpha = (sprite.alpha / 255); + extendedSprite.tint = sprite.color; + extendedSprite.x = sortableSprite.x; + extendedSprite.y = sortableSprite.y; + extendedSprite.offsetX = sprite.offsetX; + extendedSprite.offsetY = sprite.offsetY; + extendedSprite.name = sprite.name; + extendedSprite._Str_4593 = sprite._Str_4593; + extendedSprite.clickHandling = sprite.clickHandling; + extendedSprite.blendMode = sprite.blendMode; + extendedSprite.filters = sprite.filters; + + extendedSprite.setTexture(sprite.texture); + + if(sprite.updateContainer) + { + extendedSprite.addChild(sprite.container); + + sprite.updateContainer = false; + } + + if(sprite.flipH) extendedSprite.scale.x = -1; + + if(sprite.flipV) extendedSprite.scale.y = -1; + + this._Str_21914(extendedSprite, sprite); + + if((index < 0) || (index >= this._spriteCount)) + { + this._display.addChild(extendedSprite); + + this._spriteCount++; + } + else + { + this._display.addChildAt(extendedSprite, index); + } + + this._activeSpriteCount++; + } + + private _Str_20677(spriteCount: number, _arg_2: boolean = false): void + { + if(!this._display) return; + + if(spriteCount < 0) spriteCount = 0; + + if((spriteCount < this._activeSpriteCount) || !this._activeSpriteCount) + { + let iterator = (this._spriteCount - 1); + + while(iterator >= spriteCount) + { + this._Str_21974(this.getExtendedSprite(iterator), _arg_2); + + iterator--; + } + } + + this._activeSpriteCount = spriteCount; + } + + private _Str_21914(sprite: ExtendedSprite, _arg_2: IRoomObjectSprite): void + { + if(!RoomEnterEffect.isVisualizationOn() || !_arg_2) return; + + switch(_arg_2.spriteType) + { + case RoomObjectSpriteType._Str_10494: + return; + case RoomObjectSpriteType._Str_8616: + sprite.alpha = RoomEnterEffect.getDelta(0.9); + return; + case RoomObjectSpriteType._Str_11629: + sprite.alpha = RoomEnterEffect.getDelta(0.5); + return; + default: + sprite.alpha = RoomEnterEffect.getDelta(0.1); + } + } + + private _Str_21974(sprite: ExtendedSprite, _arg_2: boolean): void + { + if(!sprite) return; + + if(!_arg_2) + { + sprite.setTexture(null); + } + else + { + if(sprite.parent) sprite.parent.removeChild(sprite); + + sprite.destroy({ + children: true + }); + } + } + + public update(): void + { + if(!this._mouseCheckCount) + { + //this._Str_19207(this._mouseLocation.x, this._mouseLocation.y, MouseEventType.MOUSE_MOVE); + } + + this._mouseCheckCount = 0; + + this._eventId++; + } + + public setMouseListener(listener: IRoomCanvasMouseListener): void + { + this._mouseListener = listener; + } + + private getCacheItem(id: string): RoomObjectCacheItem + { + return this._objectCache.getObjectCache(id); + } + + private isSpriteVisible(x: number, y: number, width: number, height: number): boolean + { + if(this._noSpriteVisibilityChecking) return true; + + x = (((x - this._screenOffsetX) * this._scale) + this._screenOffsetX); + y = (((y - this._screenOffsetY) * this._scale) + this._screenOffsetY); + width = (width * this._scale); + height = (height * this._scale); + + if(((x < this._width) && ((x + width) >= 0)) && ((y < this._height) && ((y + height) >= 0))) + { + if(!this._usesExclusionRectangles) return true; + } + + return false; + } + + public _Str_21232(x: number, y: number, type: string, altKey: boolean, ctrlKey: boolean, shiftKey: boolean, buttonDown: boolean): boolean + { + x = (x - this._screenOffsetX); + y = (y - this._screenOffsetY); + + this._mouseLocation.x = (x / this._scale); + this._mouseLocation.y = (y / this._scale); + + if((this._mouseCheckCount > 0) && (type == MouseEventType.MOUSE_MOVE)) return this._mouseSpriteWasHit; + + this._mouseSpriteWasHit = this._Str_19207(Math.trunc(x / this._scale), Math.trunc(y / this._scale), type, altKey, ctrlKey, shiftKey, buttonDown); + + this._mouseCheckCount++; + + return this._mouseSpriteWasHit; + } + + private _Str_19207(x: number, y: number, type: string, altKey: boolean = false, ctrlKey: boolean = false, shiftKey: boolean = false, buttonDown: boolean = false): boolean + { + const checkedSprites: string[] = []; + + let didHitSprite = false; + let mouseEvent: RoomSpriteMouseEvent = null; + let spriteId = (this._activeSpriteCount - 1); + + while(spriteId >= 0) + { + const extendedSprite = this.getExtendedSprite(spriteId); + + if(extendedSprite && extendedSprite.containsPoint(new Point((x - extendedSprite.x), (y - extendedSprite.y)))) + { + if(extendedSprite.clickHandling && ((type === MouseEventType.MOUSE_CLICK) || (type === MouseEventType.DOUBLE_CLICK))) + { + // + } + else + { + const identifier = this.getExtendedSpriteIdentifier(extendedSprite); + + if(checkedSprites.indexOf(identifier) === -1) + { + const tag = extendedSprite.tag; + + let mouseData = this._mouseActiveObjects.get(identifier); + + if(mouseData) + { + if(mouseData.spriteTag !== tag) + { + mouseEvent = this._Str_11609(0, 0, 0, 0, MouseEventType.ROLL_OUT, mouseData.spriteTag, altKey, ctrlKey, shiftKey, buttonDown); + + this._Str_14715(mouseEvent, identifier); + } + } + + if((type === MouseEventType.MOUSE_MOVE) && (!mouseData || (mouseData.spriteTag !== tag))) + { + mouseEvent = this._Str_11609(x, y, (x - extendedSprite.x), (y - extendedSprite.y), MouseEventType.ROLL_OVER, tag, altKey, ctrlKey, shiftKey, buttonDown); + } + else + { + mouseEvent = this._Str_11609(x, y, (x - extendedSprite.x), (y - extendedSprite.y), type, tag, altKey, ctrlKey, shiftKey, buttonDown); + + mouseEvent.spriteOffsetX = extendedSprite.offsetX; + mouseEvent.spriteOffsetY = extendedSprite.offsetY; + } + + if(!mouseData) + { + mouseData = new ObjectMouseData(); + + mouseData.objectId = identifier; + this._mouseActiveObjects.set(identifier, mouseData); + } + + mouseData.spriteTag = tag; + + if(((type !== MouseEventType.MOUSE_MOVE) || (x !== this._mouseOldX)) || (y !== this._mouseOldY)) + { + this._Str_14715(mouseEvent, identifier); + } + + checkedSprites.push(identifier); + } + + didHitSprite = true; + } + } + + spriteId--; + } + + const keys: string[] = []; + + for(const key of this._mouseActiveObjects.keys()) key && keys.push(key); + + let index = 0; + + while(index < keys.length) + { + const key = keys[index]; + + if(checkedSprites.indexOf(key) >= 0) keys[index] = null; + + index++; + } + + index = 0; + + while(index < keys.length) + { + const key = keys[index]; + + if(key !== null) + { + const existing = this._mouseActiveObjects.get(key); + + if(existing) this._mouseActiveObjects.delete(key); + + const mouseEvent = this._Str_11609(0, 0, 0, 0, MouseEventType.ROLL_OUT, existing.spriteTag, altKey, ctrlKey, shiftKey, buttonDown); + + this._Str_14715(mouseEvent, key); + } + + index++; + } + + this._Str_20604(); + this._mouseOldX = x; + this._mouseOldY = y; + + return didHitSprite; + } + + protected _Str_11609(x: number, y: number, _arg_3: number, _arg_4: number, type: string, _arg_6: string, _arg_7: boolean, _arg_8: boolean, _arg_9: boolean, _arg_10: boolean): RoomSpriteMouseEvent + { + const screenX: number = (x - (this._width / 2)); + const screenY: number = (y - (this._height / 2)); + const canvasName = `canvas_${ this._id }`; + + return new RoomSpriteMouseEvent(type, ((canvasName + '_') + this._eventId), canvasName, _arg_6, screenX, screenY, _arg_3, _arg_4, _arg_8, _arg_7, _arg_9, _arg_10); + } + + protected _Str_14715(k: RoomSpriteMouseEvent, _arg_2: string): void + { + if(!k || !this._eventCache) return; + + this._eventCache.delete(_arg_2); + this._eventCache.set(_arg_2, k); + } + + protected _Str_20604(): void + { + if(!this._container || !this._eventCache) return; + + for(const [ key, event ] of this._eventCache.entries()) + { + if(!this._eventCache) return; + + if(!event) continue; + + const roomObject = this._container.getRoomObject(parseInt(key)); + + if(!roomObject) continue; + + if(this._mouseListener) + { + this._mouseListener._Str_20330(event, roomObject, this._geometry); + } + else + { + const logic = roomObject.mouseHandler; + + if(logic) + { + logic.mouseEvent(event, this._geometry); + } + } + } + + if(this._eventCache) this._eventCache.clear(); + } + + public getDisplayAsTexture(): RenderTexture + { + this._noSpriteVisibilityChecking = true; + const k = this._scale; + const _local_2 = this._screenOffsetX; + const _local_3 = this._screenOffsetY; + this.setScale(1, null, null, true); + this._screenOffsetX = 0; + this._screenOffsetY = 0; + this.render(-1, true); + + const bounds = this._display.getBounds(); + + const renderTexture = RenderTexture.create({ + width: this._display.width, + height: this._display.height + }); + + Nitro.instance.renderer.render(this._display, renderTexture, true, new Matrix(1, 0, 0, 1, -(bounds.x), -(bounds.y))); + + this._noSpriteVisibilityChecking = false; + this.setScale(k, null, null, true); + this._screenOffsetX = _local_2; + this._screenOffsetY = _local_3; + + return renderTexture; + } + + public get id(): number + { + return this._id; + } + + public get geometry(): IRoomGeometry + { + return this._geometry; + } + + public get master(): DisplayObject + { + return this._master; + } + + public get display(): DisplayObject + { + return this._display; + } + + public get screenOffsetX(): number + { + return this._screenOffsetX; + } + + public set screenOffsetX(x: number) + { + x = Math.trunc(x); + + this._mouseLocation.x = (this._mouseLocation.x - (x - this._screenOffsetX)); + this._screenOffsetX = x; + } + + public get screenOffsetY(): number + { + return this._screenOffsetY; + } + + public set screenOffsetY(y: number) + { + y = Math.trunc(y); + + this._mouseLocation.y = (this._mouseLocation.y - (y - this._screenOffsetY)); + this._screenOffsetY = y; + } + + public get scale(): number + { + return this._scale; + } + + public get width(): number + { + return (this._width * this._scale); + } + + public get height(): number + { + return (this._height * this._scale); + } + + public get restrictsScaling(): boolean + { + return this._restrictsScaling; + } + + public set restrictsScaling(flag: boolean) + { + this._restrictsScaling = flag; + } + + public get canvasUpdated(): boolean + { + return this._canvasUpdated; + } +} diff --git a/src/room/renderer/cache/RoomObjectCache.ts b/src/room/renderer/cache/RoomObjectCache.ts new file mode 100644 index 00000000..66af0995 --- /dev/null +++ b/src/room/renderer/cache/RoomObjectCache.ts @@ -0,0 +1,148 @@ +import { RoomObjectSpriteData } from '../../data/RoomObjectSpriteData'; +import { RoomObjectSpriteType } from '../../object/enum/RoomObjectSpriteType'; +import { IRoomObjectSprite } from '../../object/visualization/IRoomObjectSprite'; +import { SortableSprite } from '../utils/SortableSprite'; +import { RoomObjectCacheItem } from './RoomObjectCacheItem'; + +export class RoomObjectCache +{ + private static MAX_SIZE_FOR_AVG_COLOR: number = 200; + + private _data: Map; + private _roomObjectVariableAccurateZ: string; + + constructor(accurateZ: string) + { + this._data = new Map(); + this._roomObjectVariableAccurateZ = accurateZ; + } + + public dispose(): void + { + if(this._data) + { + for(const [ key, item ] of this._data.entries()) + { + if(!item) continue; + + this._data.delete(key); + + item.dispose(); + } + + this._data = null; + } + } + + public getObjectCache(k: string): RoomObjectCacheItem + { + let existing = this._data.get(k); + + if(!existing) + { + existing = new RoomObjectCacheItem(this._roomObjectVariableAccurateZ); + + this._data.set(k, existing); + } + + return existing; + } + + public removeObjectCache(k: string): void + { + const existing = this._data.get(k); + + if(!existing) return; + + this._data.delete(k); + + existing.dispose(); + } + + public getSortableSpriteList(): RoomObjectSpriteData[] + { + const spriteData: RoomObjectSpriteData[] = []; + + for(const item of this._data.values()) + { + if(!item) continue; + + const sprites = item.sprites && item.sprites._Str_9272; + + if(!sprites || !sprites.length) continue; + + for(const sprite of sprites) + { + if(!sprite) continue; + + if((sprite.sprite.spriteType !== RoomObjectSpriteType._Str_8616) && (sprite.sprite.name !== '')) + { + const data = new RoomObjectSpriteData(); + + data.objectId = item._Str_1577; + data.x = sprite.x; + data.y = sprite.y; + data.z = sprite.z; + data.name = sprite.sprite.name || ''; + data.flipH = sprite.sprite.flipH; + data.alpha = sprite.sprite.alpha; + data.color = sprite.sprite.color.toString(); + data.blendMode = sprite.sprite.blendMode.toString(); + data.width = sprite.sprite.width; + data.height = sprite.sprite.height; + data.type = sprite.sprite.type; + data.posture = sprite.sprite.posture; + + const isSkewed = this.isSkewedSprite(sprite.sprite); + + if(isSkewed) + { + data.skew = (((sprite.sprite.direction % 4) === 0) ? -0.5 : 0.5); + } + + if(((((isSkewed || (sprite.name.indexOf('%image.library.url%') >= 0)) || (sprite.name.indexOf('%group.badge.url%') >= 0)) && (data.width <= RoomObjectCache.MAX_SIZE_FOR_AVG_COLOR)) && (data.height <= RoomObjectCache.MAX_SIZE_FOR_AVG_COLOR))) + { + //data.color = Canvas._Str_23439(sprite.sprite.texture).toString(); + + if(sprite.sprite.name.indexOf('external_image_wallitem') === 0) + { + data.frame = true; + } + } + + spriteData.push(data); + } + } + } + + if(!spriteData || !spriteData.length) return null; + + return spriteData; + } + + private isSkewedSprite(k: IRoomObjectSprite): boolean + { + if(!k.type) return false; + + if((k.type.indexOf('external_image_wallitem') === 0) && (k.tag === 'THUMBNAIL')) return true; + + if((k.type.indexOf('guild_forum') === 0) && (k.tag === 'THUMBNAIL')) return true; + + return false; + } + + public getPlaneSortableSprites(): SortableSprite[] + { + const sprites: SortableSprite[] = []; + + for(const item of this._data.values()) + { + for(const sprite of item.sprites._Str_9272) + { + if(sprite.sprite.spriteType === RoomObjectSpriteType._Str_8616) sprites.push(sprite); + } + } + + return sprites; + } +} \ No newline at end of file diff --git a/src/room/renderer/cache/RoomObjectCacheItem.ts b/src/room/renderer/cache/RoomObjectCacheItem.ts new file mode 100644 index 00000000..8bcc0afe --- /dev/null +++ b/src/room/renderer/cache/RoomObjectCacheItem.ts @@ -0,0 +1,52 @@ +import { RoomObjectLocationCacheItem } from './RoomObjectLocationCacheItem'; +import { RoomObjectSortableSpriteCacheItem } from './RoomObjectSortableSpriteCacheItem'; + +export class RoomObjectCacheItem +{ + private _objectId: number; + private _location: RoomObjectLocationCacheItem; + private _sprites: RoomObjectSortableSpriteCacheItem; + + constructor(accurateZ: string) + { + this._location = new RoomObjectLocationCacheItem(accurateZ); + this._sprites = new RoomObjectSortableSpriteCacheItem(); + } + + public get location(): RoomObjectLocationCacheItem + { + return this._location; + } + + public get sprites(): RoomObjectSortableSpriteCacheItem + { + return this._sprites; + } + + public dispose(): void + { + if(this._location) + { + this._location.dispose(); + + this._location = null; + } + + if(this._sprites) + { + this._sprites.dispose(); + + this._sprites = null; + } + } + + public get _Str_1577(): number + { + return this._objectId; + } + + public set _Str_1577(k:number) + { + this._objectId = k; + } +} \ No newline at end of file diff --git a/src/room/renderer/cache/RoomObjectLocationCacheItem.ts b/src/room/renderer/cache/RoomObjectLocationCacheItem.ts new file mode 100644 index 00000000..d773ff2a --- /dev/null +++ b/src/room/renderer/cache/RoomObjectLocationCacheItem.ts @@ -0,0 +1,98 @@ +import { IRoomObject } from '../../object/IRoomObject'; +import { IRoomGeometry } from '../../utils/IRoomGeometry'; +import { IVector3D } from '../../utils/IVector3D'; +import { Vector3d } from '../../utils/Vector3d'; + +export class RoomObjectLocationCacheItem +{ + private _roomObjectVariableAccurateZ: string; + + private _location: Vector3d; + private _screenLocation: Vector3d; + private _locationChanged: boolean; + + private _geometryUpdateId: number; + private _objectUpdateId: number; + + constructor(accurateZ: string) + { + this._roomObjectVariableAccurateZ = accurateZ || ''; + + this._location = new Vector3d(); + this._screenLocation = new Vector3d(); + this._locationChanged = false; + + this._geometryUpdateId = -1; + this._objectUpdateId = -1; + } + + public dispose(): void + { + this._screenLocation = null; + } + + public updateLocation(object: IRoomObject, geometry: IRoomGeometry): IVector3D + { + if(!object || !geometry) return null; + + let locationChanged = false; + + const location = object.getLocation(); + + if((geometry.updateId !== this._geometryUpdateId) || (object.updateCounter !== this._objectUpdateId)) + { + this._objectUpdateId = object.updateCounter; + + if((geometry.updateId !== this._geometryUpdateId) || (location.x !== this._location.x) || (location.y !== this._location.y) || (location.z !== this._location.z)) + { + this._geometryUpdateId = geometry.updateId; + this._location.assign(location); + + locationChanged = true; + } + } + + this._locationChanged = locationChanged; + + if(this._locationChanged) + { + const screenLocation = geometry.getScreenPosition(location); + + if(!screenLocation) return null; + + const accurateZ = object.model.getValue(this._roomObjectVariableAccurateZ); + + if(isNaN(accurateZ) || (accurateZ === 0)) + { + const rounded = new Vector3d(Math.round(location.x), Math.round(location.y), location.z); + + if((rounded.x !== location.x) || (rounded.y !== location.y)) + { + const roundedScreen = geometry.getScreenPosition(rounded); + + this._screenLocation.assign(screenLocation); + + if(roundedScreen) this._screenLocation.z = roundedScreen.z; + } + else + { + this._screenLocation.assign(screenLocation); + } + } + else + { + this._screenLocation.assign(screenLocation); + } + + this._screenLocation.x = Math.round(this._screenLocation.x); + this._screenLocation.y = Math.round(this._screenLocation.y); + } + + return this._screenLocation; + } + + public get locationChanged(): boolean + { + return this._locationChanged; + } +} \ No newline at end of file diff --git a/src/room/renderer/cache/RoomObjectSortableSpriteCacheItem.ts b/src/room/renderer/cache/RoomObjectSortableSpriteCacheItem.ts new file mode 100644 index 00000000..808c3680 --- /dev/null +++ b/src/room/renderer/cache/RoomObjectSortableSpriteCacheItem.ts @@ -0,0 +1,78 @@ +import { SortableSprite } from '../utils/SortableSprite'; + +export class RoomObjectSortableSpriteCacheItem +{ + private _sprites: SortableSprite[]; + private _updateId1: number; + private _updateId2: number; + private _isEmpty: boolean; + + constructor() + { + this._sprites = []; + this._updateId1 = -1; + this._updateId2 = -1; + this._isEmpty = false; + } + + public get _Str_3008(): number + { + return this._sprites.length; + } + + public get isEmpty(): boolean + { + return this._isEmpty; + } + + public dispose(): void + { + this._Str_20276(0); + } + + public _Str_12937(sprite: SortableSprite): void + { + this._sprites.push(sprite); + } + + public _Str_2505(k: number): SortableSprite + { + return this._sprites[k]; + } + + public get _Str_9272(): SortableSprite[] + { + return this._sprites; + } + + public _Str_17574(k: number, _arg_2: number): boolean + { + if((k === this._updateId1) && (_arg_2 === this._updateId2)) return false; + + this._updateId1 = k; + this._updateId2 = _arg_2; + + return true; + } + + public _Str_20276(k: number): void + { + if(k < this._sprites.length) + { + let iterator = k; + + while(iterator < this._sprites.length) + { + const sprite = this._sprites[iterator]; + + if(sprite) sprite.dispose(); + + iterator++; + } + + this._sprites.splice(k, (this._sprites.length - k)); + } + + this._isEmpty = (this._sprites.length) ? false : true; + } +} \ No newline at end of file diff --git a/src/room/renderer/utils/ExtendedSprite.ts b/src/room/renderer/utils/ExtendedSprite.ts new file mode 100644 index 00000000..9b6ad263 --- /dev/null +++ b/src/room/renderer/utils/ExtendedSprite.ts @@ -0,0 +1,241 @@ +import { BaseTexture, BLEND_MODES, Point, Renderer, RenderTexture, Sprite, Texture } from 'pixi.js'; +import { Nitro } from '../../../nitro/Nitro'; + +export class ExtendedSprite extends Sprite +{ + private _offsetX: number; + private _offsetY: number; + private _tag: string; + private _alphaTolerance: number; + private _Str_8253: boolean; + private _clickHandling: boolean; + + private _pairedSpriteId: number; + private _pairedSpriteUpdateCounter: number; + + constructor(texture: Texture = null) + { + super(texture); + + this._offsetX = 0; + this._offsetY = 0; + this._tag = ''; + this._alphaTolerance = 128; + this._Str_8253 = false; + this._clickHandling = false; + + this._pairedSpriteId = -1; + this._pairedSpriteUpdateCounter = -1; + } + + public needsUpdate(pairedSpriteId: number, pairedSpriteUpdateCounter: number): boolean + { + if((this._pairedSpriteId === pairedSpriteId) && (this._pairedSpriteUpdateCounter === pairedSpriteUpdateCounter)) return false; + + this._pairedSpriteId = pairedSpriteId; + this._pairedSpriteUpdateCounter = pairedSpriteUpdateCounter; + + return true; + } + + public render(renderer: Renderer): void + { + try + { + //@ts-ignore + if(!this._texture || !this._texture._uvs || !this._texture._uvs.uvsFloat32) return; + } + + catch (err) + { + return; + } + + super.render(renderer); + } + + public setTexture(texture: Texture): void + { + if(!texture) texture = Texture.EMPTY; + + if(texture === this.texture) return; + + if(texture === Texture.EMPTY) + { + this._pairedSpriteId = -1; + this._pairedSpriteUpdateCounter = -1; + } + + this.texture = texture; + } + + public containsPoint(point: Point): boolean + { + return ExtendedSprite.containsPoint(this, point); + } + + public static containsPoint(sprite: ExtendedSprite, point: Point): boolean + { + if(!sprite || !point || (sprite.alphaTolerance > 255)) return false; + + if(!(sprite instanceof Sprite)) return false; + + if((sprite.texture === Texture.EMPTY) || (sprite.blendMode !== BLEND_MODES.NORMAL)) return; + + const texture = sprite.texture; + const baseTexture = texture.baseTexture; + + if(!texture || !baseTexture || !baseTexture.valid) return false; + + const x = (point.x * sprite.scale.x); + const y = (point.y * sprite.scale.y); + + if(!sprite.getLocalBounds().contains(x, y)) return false; + + //@ts-ignore + if(!baseTexture.hitMap) + { + let canvas: HTMLCanvasElement = null; + + if(!baseTexture.resource) + { + //@ts-ignore + if(!texture.getLocalBounds) + { + const tempSprite = Sprite.from(texture); + + canvas = Nitro.instance.renderer.extract.canvas(tempSprite); + + tempSprite.destroy(); + } + else + { + canvas = Nitro.instance.renderer.extract.canvas(texture as RenderTexture); + } + } + + if(!ExtendedSprite.generateHitMap(baseTexture, canvas)) return false; + } + + //@ts-ignore + const hitMap = baseTexture.hitMap; + //@ts-ignore + const width = baseTexture.hitMapWidth; + const resolution = baseTexture.resolution; + const dx = Math.round((x + texture.frame.x) * resolution); + const dy = Math.round((y + texture.frame.y) * resolution); + const index = (((dy * width) + dx) * 4); + + return ((hitMap[index + 3] !== undefined) && (hitMap[index + 3] > sprite.alphaTolerance)); + } + + private static generateHitMap(baseTexture: BaseTexture, tempCanvas: HTMLCanvasElement = null): boolean + { + let canvas: HTMLCanvasElement = null; + let context: CanvasRenderingContext2D = null; + + if(tempCanvas) + { + canvas = tempCanvas; + context = canvas.getContext('2d'); + } + else + { + if(!baseTexture.resource) return false; + + //@ts-ignore + const source = baseTexture.resource.source as HTMLCanvasElement; + + if(!source) return false; + + if(source.getContext) + { + canvas = source; + context = canvas.getContext('2d'); + } + + else if(source instanceof Image) + { + canvas = document.createElement('canvas'); + canvas.width = source.width; + canvas.height = source.height; + context = canvas.getContext('2d'); + + context.drawImage(source, 0, 0); + } + + else return false; + } + + const width = canvas.width; + const height = canvas.height; + const imageData = context.getImageData(0, 0, width, height); + + //@ts-ignore + baseTexture.hitMap = imageData.data; + //@ts-ignore + baseTexture.hitMapWidth = width; + + return true; + } + + public get offsetX(): number + { + return this._offsetX; + } + + public set offsetX(offset: number) + { + this._offsetX = offset; + } + + public get offsetY(): number + { + return this._offsetY; + } + + public set offsetY(offset: number) + { + this._offsetY = offset; + } + + public get tag(): string + { + return this._tag; + } + + public set tag(tag: string) + { + this._tag = tag; + } + + public get alphaTolerance(): number + { + return this._alphaTolerance; + } + + public set alphaTolerance(tolerance: number) + { + this._alphaTolerance = tolerance; + } + + public get _Str_4593(): boolean + { + return this._Str_8253; + } + + public set _Str_4593(flag: boolean) + { + this._Str_8253 = flag; + } + + public get clickHandling(): boolean + { + return this._clickHandling; + } + + public set clickHandling(flag: boolean) + { + this._clickHandling = flag; + } +} diff --git a/src/room/renderer/utils/ObjectMouseData.ts b/src/room/renderer/utils/ObjectMouseData.ts new file mode 100644 index 00000000..3ab52075 --- /dev/null +++ b/src/room/renderer/utils/ObjectMouseData.ts @@ -0,0 +1,31 @@ +export class ObjectMouseData +{ + private _objectId: string; + private _spriteTag: string; + + constructor() + { + this._objectId = ''; + this._spriteTag = ''; + } + + public get objectId(): string + { + return this._objectId; + } + + public set objectId(k: string) + { + this._objectId = k; + } + + public get spriteTag(): string + { + return this._spriteTag; + } + + public set spriteTag(k: string) + { + this._spriteTag = k; + } +} \ No newline at end of file diff --git a/src/room/renderer/utils/SortableSprite.ts b/src/room/renderer/utils/SortableSprite.ts new file mode 100644 index 00000000..cbe34c72 --- /dev/null +++ b/src/room/renderer/utils/SortableSprite.ts @@ -0,0 +1,80 @@ +import { IRoomObjectSprite } from '../../object/visualization/IRoomObjectSprite'; +import { ISortableSprite } from '../../object/visualization/ISortableSprite'; + +export class SortableSprite implements ISortableSprite +{ + public static _Str_17154: number = 100000000; + + private _name: string; + private _sprite: IRoomObjectSprite; + + private _x: number; + private _y: number; + private _z: number; + + constructor() + { + this._name = ''; + this._sprite = null; + + this._x = 0; + this._y = 0; + this._z = 0; + } + + public dispose(): void + { + this._z = -(SortableSprite._Str_17154); + this._sprite = null; + } + + public get name(): string + { + return this._name; + } + + public set name(name: string) + { + this._name = name; + } + + public get sprite(): IRoomObjectSprite + { + return this._sprite; + } + + public set sprite(sprite: IRoomObjectSprite) + { + this._sprite = sprite; + } + + public get x(): number + { + return this._x; + } + + public set x(x: number) + { + this._x = x; + } + + public get y(): number + { + return this._y; + } + + public set y(y: number) + { + this._y = y; + } + + public get z(): number + { + return this._z; + } + + public set z(z: number) + { + this._z = z; + } +} \ No newline at end of file diff --git a/src/room/utils/ColorConverter.ts b/src/room/utils/ColorConverter.ts new file mode 100644 index 00000000..81563d95 --- /dev/null +++ b/src/room/utils/ColorConverter.ts @@ -0,0 +1,324 @@ +import { IVector3D } from './IVector3D'; +import { Vector3d } from './Vector3d'; + +export class ColorConverter +{ + private static HEX_DIGITS = [ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' ]; + + public static hex2rgb(hex: number, out: Array | Float32Array = []): Array | Float32Array + { + out[0] = ((hex >> 16) & 0xFF) / 255; + out[1] = ((hex >> 8) & 0xFF) / 255; + out[2] = (hex & 0xFF) / 255; + + return out; + } + + public static rgb2hex(rgb: number[] | Float32Array): number + { + return (((rgb[0] * 255) << 16) + ((rgb[1] * 255) << 8) + (rgb[2] * 255 | 0)); + } + + public static rgbStringToHex(rgb: string): string + { + const extracted = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/); + + return '#' + ColorConverter.getHex(extracted[1]) + ColorConverter.getHex(extracted[2]) + ColorConverter.getHex(extracted[3]); + } + + public static getHex(x: any) + { + return isNaN(x) ? '00' : ColorConverter.HEX_DIGITS[(x - x % 16) / 16] + ColorConverter.HEX_DIGITS[x % 16]; + } + + public static int2rgb(color: number): string + { + color >>>= 0; + const b = color & 0xFF; + const g = (color & 0xFF00) >>> 8; + const r = (color & 0xFF0000) >>> 16; + const a = ( (color & 0xFF000000) >>> 24 ) / 255; + + return 'rgba(' + [r, g, b, 1].join(',') + ')'; + } + + public static _Str_22130(k: number): number + { + const _local_2: number = (((k >> 16) & 0xFF) / 0xFF); + const _local_3: number = (((k >> 8) & 0xFF) / 0xFF); + const _local_4: number = ((k & 0xFF) / 0xFF); + const _local_5: number = Math.max(_local_2, _local_3, _local_4); + const _local_6: number = Math.min(_local_2, _local_3, _local_4); + const _local_7: number = (_local_5 - _local_6); + let _local_8 = 0; + let _local_9 = 0; + let _local_10 = 0; + if(_local_7 == 0) + { + _local_8 = 0; + } + else + { + if(_local_5 == _local_2) + { + if(_local_3 > _local_4) + { + _local_8 = ((60 * (_local_3 - _local_4)) / _local_7); + } + else + { + _local_8 = (((60 * (_local_3 - _local_4)) / _local_7) + 360); + } + } + else + { + if(_local_5 == _local_3) + { + _local_8 = (((60 * (_local_4 - _local_2)) / _local_7) + 120); + } + else + { + if(_local_5 == _local_4) + { + _local_8 = (((60 * (_local_2 - _local_3)) / _local_7) + 240); + } + } + } + } + _local_9 = (0.5 * (_local_5 + _local_6)); + if(_local_7 == 0) + { + _local_10 = 0; + } + else + { + if(_local_9 <= 0.5) + { + _local_10 = ((_local_7 / _local_9) * 0.5); + } + else + { + _local_10 = ((_local_7 / (1 - _local_9)) * 0.5); + } + } + const _local_11: number = Math.round(((_local_8 / 360) * 0xFF)); + const _local_12: number = Math.round((_local_10 * 0xFF)); + const _local_13: number = Math.round((_local_9 * 0xFF)); + const _local_14: number = (((_local_11 << 16) + (_local_12 << 8)) + _local_13); + return _local_14; + } + + public static _Str_13949(k: number): number + { + let _local_12: number; + let _local_13: number; + let _local_14: number; + let _local_15: number; + let _local_16: number; + const _local_2: number = (((k >> 16) & 0xFF) / 0xFF); + const _local_3: number = (((k >> 8) & 0xFF) / 0xFF); + const _local_4: number = ((k & 0xFF) / 0xFF); + let _local_5 = 0; + let _local_6 = 0; + let _local_7 = 0; + if(_local_3 > 0) + { + _local_12 = 0; + _local_13 = 0; + if(_local_4 < 0.5) + { + _local_12 = (_local_4 * (1 + _local_3)); + } + else + { + _local_12 = ((_local_4 + _local_3) - (_local_4 * _local_3)); + } + _local_13 = ((2 * _local_4) - _local_12); + _local_14 = (_local_2 + (1 / 3)); + _local_15 = _local_2; + _local_16 = (_local_2 - (1 / 3)); + if(_local_14 < 0) + { + _local_14 = (_local_14 + 1); + } + else + { + if(_local_14 > 1) + { + _local_14--; + } + } + if(_local_15 < 0) + { + _local_15 = (_local_15 + 1); + } + else + { + if(_local_15 > 1) + { + _local_15--; + } + } + if(_local_16 < 0) + { + _local_16 = (_local_16 + 1); + } + else + { + if(_local_16 > 1) + { + _local_16--; + } + } + if((_local_14 * 6) < 1) + { + _local_5 = (_local_13 + (((_local_12 - _local_13) * 6) * _local_14)); + } + else + { + if((_local_14 * 2) < 1) + { + _local_5 = _local_12; + } + else + { + if((_local_14 * 3) < 2) + { + _local_5 = (_local_13 + (((_local_12 - _local_13) * 6) * ((2 / 3) - _local_14))); + } + else + { + _local_5 = _local_13; + } + } + } + if((_local_15 * 6) < 1) + { + _local_6 = (_local_13 + (((_local_12 - _local_13) * 6) * _local_15)); + } + else + { + if((_local_15 * 2) < 1) + { + _local_6 = _local_12; + } + else + { + if((_local_15 * 3) < 2) + { + _local_6 = (_local_13 + (((_local_12 - _local_13) * 6) * ((2 / 3) - _local_15))); + } + else + { + _local_6 = _local_13; + } + } + } + if((_local_16 * 6) < 1) + { + _local_7 = (_local_13 + (((_local_12 - _local_13) * 6) * _local_16)); + } + else + { + if((_local_16 * 2) < 1) + { + _local_7 = _local_12; + } + else + { + if((_local_16 * 3) < 2) + { + _local_7 = (_local_13 + (((_local_12 - _local_13) * 6) * ((2 / 3) - _local_16))); + } + else + { + _local_7 = _local_13; + } + } + } + } + else + { + _local_5 = _local_4; + _local_6 = _local_4; + _local_7 = _local_4; + } + const _local_8: number = Math.round((_local_5 * 0xFF)); + const _local_9: number = Math.round((_local_6 * 0xFF)); + const _local_10: number = Math.round((_local_7 * 0xFF)); + const _local_11: number = (((_local_8 << 16) + (_local_9 << 8)) + _local_10); + return _local_11; + } + + public static rgb2xyz(k: number): IVector3D + { + let _local_2: number = (((k >> 16) & 0xFF) / 0xFF); + let _local_3: number = (((k >> 8) & 0xFF) / 0xFF); + let _local_4: number = (((k >> 0) & 0xFF) / 0xFF); + if(_local_2 > 0.04045) + { + _local_2 = Math.pow(((_local_2 + 0.055) / 1.055), 2.4); + } + else + { + _local_2 = (_local_2 / 12.92); + } + if(_local_3 > 0.04045) + { + _local_3 = Math.pow(((_local_3 + 0.055) / 1.055), 2.4); + } + else + { + _local_3 = (_local_3 / 12.92); + } + if(_local_4 > 0.04045) + { + _local_4 = Math.pow(((_local_4 + 0.055) / 1.055), 2.4); + } + else + { + _local_4 = (_local_4 / 12.92); + } + _local_2 = (_local_2 * 100); + _local_3 = (_local_3 * 100); + _local_4 = (_local_4 * 100); + return new Vector3d((((_local_2 * 0.4124) + (_local_3 * 0.3576)) + (_local_4 * 0.1805)), (((_local_2 * 0.2126) + (_local_3 * 0.7152)) + (_local_4 * 0.0722)), (((_local_2 * 0.0193) + (_local_3 * 0.1192)) + (_local_4 * 0.9505))); + } + + public static _Str_22784(k:IVector3D):IVector3D + { + let _local_2: number = (k.x / 95.047); + let _local_3: number = (k.y / 100); + let _local_4: number = (k.z / 108.883); + if(_local_2 > 0.008856) + { + _local_2 = Math.pow(_local_2, (1 / 3)); + } + else + { + _local_2 = ((7.787 * _local_2) + (16 / 116)); + } + if(_local_3 > 0.008856) + { + _local_3 = Math.pow(_local_3, (1 / 3)); + } + else + { + _local_3 = ((7.787 * _local_3) + (16 / 116)); + } + if(_local_4 > 0.008856) + { + _local_4 = Math.pow(_local_4, (1 / 3)); + } + else + { + _local_4 = ((7.787 * _local_4) + (16 / 116)); + } + return new Vector3d(((116 * _local_3) - 16), (500 * (_local_2 - _local_3)), (200 * (_local_3 - _local_4))); + } + + public static rgb2CieLab(k: number):IVector3D + { + return ColorConverter._Str_22784(ColorConverter.rgb2xyz(k)); + } +} diff --git a/src/room/utils/IRoomGeometry.ts b/src/room/utils/IRoomGeometry.ts new file mode 100644 index 00000000..4b4cb9c4 --- /dev/null +++ b/src/room/utils/IRoomGeometry.ts @@ -0,0 +1,21 @@ +import { Point } from 'pixi.js'; +import { IVector3D } from './IVector3D'; + +export interface IRoomGeometry +{ + getCoordinatePosition(_arg_1: IVector3D): IVector3D; + getScreenPoint(_arg_1: IVector3D): Point; + getScreenPosition(_arg_1: IVector3D): IVector3D; + getPlanePosition(_arg_1: Point, _arg_2: IVector3D, _arg_3: IVector3D, _arg_4: IVector3D): Point; + setDisplacement(_arg_1: IVector3D, _arg_2: IVector3D): void; + adjustLocation(_arg_1: IVector3D, _arg_2: number): void; + performZoom(): void; + performZoomOut(): void; + performZoomIn(): void; + isZoomedIn(): boolean; + updateId: number; + z_scale: number; + scale: number; + directionAxis: IVector3D; + direction: IVector3D; +} \ No newline at end of file diff --git a/src/room/utils/IVector3D.ts b/src/room/utils/IVector3D.ts new file mode 100644 index 00000000..703a41f8 --- /dev/null +++ b/src/room/utils/IVector3D.ts @@ -0,0 +1,7 @@ +export interface IVector3D +{ + x: number; + y: number; + z: number; + length: number; +} diff --git a/src/room/utils/NumberBank.ts b/src/room/utils/NumberBank.ts new file mode 100644 index 00000000..a9cca763 --- /dev/null +++ b/src/room/utils/NumberBank.ts @@ -0,0 +1,54 @@ +export class NumberBank +{ + private _reservedNumbers: number[]; + private _freeNumbers: number[]; + + constructor(k: number) + { + if(k < 0) k = 0; + + this._reservedNumbers = []; + this._freeNumbers = []; + + let i = 0; + + while(i < k) + { + this._freeNumbers.push(i); + + i++; + } + } + + public dispose(): void + { + this._reservedNumbers = null; + this._freeNumbers = null; + } + + public _Str_19709(): number + { + if(this._freeNumbers.length > 0) + { + const k = this._freeNumbers.pop(); + + this._reservedNumbers.push(k); + + return k; + } + + return -1; + } + + public _Str_15187(k: number): void + { + const i = this._reservedNumbers.indexOf(k); + + if(i >= 0) + { + this._reservedNumbers.splice(i, 1); + + this._freeNumbers.push(k); + } + } +} \ No newline at end of file diff --git a/src/room/utils/PointMath.ts b/src/room/utils/PointMath.ts new file mode 100644 index 00000000..aaa112e2 --- /dev/null +++ b/src/room/utils/PointMath.ts @@ -0,0 +1,19 @@ +import { Point } from 'pixi.js'; + +export class PointMath +{ + public static sum(k: Point, _arg_2: Point): Point + { + return new Point((k.x + _arg_2.x), (k.y + _arg_2.y)); + } + + public static _Str_15193(k: Point, _arg_2: Point): Point + { + return new Point((k.x - _arg_2.x), (k.y - _arg_2.y)); + } + + public static _Str_6038(k: Point, _arg_2: number): Point + { + return new Point((k.x * _arg_2), (k.y * _arg_2)); + } +} \ No newline at end of file diff --git a/src/room/utils/Rasterizer.ts b/src/room/utils/Rasterizer.ts new file mode 100644 index 00000000..091e29a5 --- /dev/null +++ b/src/room/utils/Rasterizer.ts @@ -0,0 +1,129 @@ +import { Graphics, Matrix, Texture } from 'pixi.js'; +import { TextureUtils } from './TextureUtils'; + +export class Rasterizer +{ + // public static line(k:BitmapData, _arg_2: Point, _arg_3: Point, _arg_4: number): void + // { + // var _local_5:int; + // var _local_6:int; + // var _local_7:int; + // var _local_8:int; + // var _local_9:int; + // var _local_10:int; + // var _local_11:int = _arg_2.x; + // var _local_12:int = _arg_2.y; + // _local_5 = (_arg_3.x - _arg_2.x); + // _local_6 = (_arg_3.y - _arg_2.y); + // _local_8 = ((_local_5 > 0) ? 1 : -1); + // _local_9 = ((_local_6 > 0) ? 1 : -1); + // _local_5 = Math.abs(_local_5); + // _local_6 = Math.abs(_local_6); + // k.lock(); + // k.setPixel32(_local_11, _local_12, _arg_4); + // if (((_local_5 == 0) && (_local_6 == 0))) + // { + // return; + // } + // if (_local_5 > _local_6) + // { + // _local_7 = (_local_5 - 1); + // while (_local_7 >= 0) + // { + // _local_10 = (_local_10 + _local_6); + // _local_11 = (_local_11 + _local_8); + // if (_local_10 >= (_local_5 / 2)) + // { + // _local_10 = (_local_10 - _local_5); + // _local_12 = (_local_12 + _local_9); + // } + // k.setPixel32(_local_11, _local_12, _arg_4); + // _local_7--; + // } + // } + // else + // { + // _local_7 = (_local_6 - 1); + // while (_local_7 >= 0) + // { + // _local_10 = (_local_10 + _local_5); + // _local_12 = (_local_12 + _local_9); + // if (_local_10 >= (_local_6 / 2)) + // { + // _local_10 = (_local_10 - _local_6); + // _local_11 = (_local_11 + _local_8); + // } + // k.setPixel32(_local_11, _local_12, _arg_4); + // _local_7--; + // } + // } + // k.setPixel32(_arg_3.x, _arg_3.y, _arg_4); + // k.unlock(); + // } + + public static _Str_16640(k: Texture): Texture + { + if(!k) return null; + + const matrix = new Matrix(); + + matrix.scale(-1, 1); + matrix.translate(k.width, 0); + + const graphic = new Graphics(); + + graphic + .beginTextureFill({ + texture: k, + matrix + }) + .drawRect(0, 0, k.width, k.height) + .endFill(); + + return TextureUtils.generateTexture(graphic); + } + + public static _Str_20706(k: Texture): Texture + { + if(!k) return null; + + const matrix = new Matrix(); + + matrix.scale(1, -1); + matrix.translate(0, k.height); + + const graphic = new Graphics(); + + graphic + .beginTextureFill({ + texture: k, + matrix + }) + .drawRect(0, 0, k.width, k.height) + .endFill(); + + return TextureUtils.generateTexture(graphic); + } + + public static _Str_20356(k: Texture): Texture + { + if(!k) return null; + + const matrix = new Matrix(); + + matrix.scale(-1, -1); + matrix.translate(k.width, k.height); + + const graphic = new Graphics(); + + graphic + .beginTextureFill({ + texture: k, + matrix + }) + .drawRect(0, 0, k.width, k.height) + .endFill(); + + return TextureUtils.generateTexture(graphic); + } +} \ No newline at end of file diff --git a/src/room/utils/RoomEnterEffect.ts b/src/room/utils/RoomEnterEffect.ts new file mode 100644 index 00000000..30dcc667 --- /dev/null +++ b/src/room/utils/RoomEnterEffect.ts @@ -0,0 +1,78 @@ +import { Nitro } from '../../nitro/Nitro'; + +export class RoomEnterEffect +{ + public static STATE_NOT_INITIALIZED: number = 0; + public static STATE_START_DELAY: number = 1; + public static STATE_RUNNING: number = 2; + public static STATE_OVER: number = 3; + + private static _state: number = RoomEnterEffect.STATE_NOT_INITIALIZED; + private static _visualizationOn: boolean = false; + private static _currentDelta: number = 0; + private static _initializationTimeMs: number = 0; + private static _startDelayMs: number = (20 * 1000); + private static _effectDurationMs: number = 2000; + + public static init(delay: number, duration: number): void + { + RoomEnterEffect._currentDelta = 0; + RoomEnterEffect._startDelayMs = delay; + RoomEnterEffect._effectDurationMs = duration; + RoomEnterEffect._initializationTimeMs = Nitro.instance.time; + RoomEnterEffect._state = RoomEnterEffect.STATE_START_DELAY; + } + + public static turnVisualizationOn(): void + { + if((RoomEnterEffect._state === RoomEnterEffect.STATE_NOT_INITIALIZED) || (RoomEnterEffect._state === RoomEnterEffect.STATE_OVER)) return; + + const k = (Nitro.instance.time - RoomEnterEffect._initializationTimeMs); + + if(k > (RoomEnterEffect._startDelayMs + RoomEnterEffect._effectDurationMs)) + { + RoomEnterEffect._state = RoomEnterEffect.STATE_OVER; + + return; + } + + RoomEnterEffect._visualizationOn = true; + + if(k < RoomEnterEffect._startDelayMs) + { + RoomEnterEffect._state = RoomEnterEffect.STATE_START_DELAY; + + return; + } + + RoomEnterEffect._state = RoomEnterEffect.STATE_RUNNING; + RoomEnterEffect._currentDelta = ((k - RoomEnterEffect._startDelayMs) / RoomEnterEffect._effectDurationMs); + } + + public static turnVisualizationOff(): void + { + RoomEnterEffect._visualizationOn = false; + } + + public static isVisualizationOn(): boolean + { + return (RoomEnterEffect._visualizationOn) && (RoomEnterEffect.isRunning()); + } + + public static isRunning(): boolean + { + if((RoomEnterEffect._state === RoomEnterEffect.STATE_START_DELAY) || (RoomEnterEffect._state === RoomEnterEffect.STATE_RUNNING)) return true; + + return false; + } + + public static getDelta(k: number = 0, _arg_2: number = 1): number + { + return Math.min(Math.max(RoomEnterEffect._currentDelta, k), _arg_2); + } + + public static get totalRunningTime(): number + { + return RoomEnterEffect._startDelayMs + RoomEnterEffect._effectDurationMs; + } +} diff --git a/src/room/utils/RoomGeometry.ts b/src/room/utils/RoomGeometry.ts new file mode 100644 index 00000000..e140ad11 --- /dev/null +++ b/src/room/utils/RoomGeometry.ts @@ -0,0 +1,433 @@ +import { Point } from 'pixi.js'; +import { IRoomGeometry } from './IRoomGeometry'; +import { IVector3D } from './IVector3D'; +import { Vector3d } from './Vector3d'; + +export class RoomGeometry implements IRoomGeometry +{ + public static SCALE_ZOOMED_IN: number = 64; + public static SCALE_ZOOMED_OUT: number = 32; + + private _updateId: number = 0; + private _x: Vector3d; + private _y: Vector3d; + private _z: Vector3d; + private _directionAxis: Vector3d; + private _location: Vector3d; + private _direction: Vector3d; + private _depth: Vector3d; + private _scale: number = 1; + private _x_scale: number = 1; + private _y_scale: number = 1; + private _z_scale: number = 1; + private _x_scale_internal: number = 1; + private _y_scale_internal: number = 1; + private _z_scale_internal: number = 1; + private _loc: Vector3d; + private _dir: Vector3d; + private _clipNear: number = -500; + private _clipFar: number = 500; + private _displacements: Map = null; + + constructor(scale: number, direction: IVector3D, location: IVector3D, _arg_4: IVector3D = null) + { + this.scale = scale; + this._x = new Vector3d(); + this._y = new Vector3d(); + this._z = new Vector3d(); + this._directionAxis = new Vector3d(); + this._location = new Vector3d(); + this._direction = new Vector3d(); + this._depth = new Vector3d(); + this._x_scale_internal = 1; + this._y_scale_internal = 1; + this.x_scale = 1; + this.y_scale = 1; + this._z_scale_internal = (Math.sqrt((1 / 2)) / Math.sqrt((3 / 4))); + this.z_scale = 1; + this.location = new Vector3d(location.x, location.y, location.z); + this.direction = new Vector3d(direction.x, direction.y, direction.z); + if(_arg_4 != null) + { + this.setDepthVector(_arg_4); + } + else + { + this.setDepthVector(direction); + } + this._displacements = new Map(); + } + + public static getIntersectionVector(k: IVector3D, _arg_2: IVector3D, _arg_3: IVector3D, _arg_4: IVector3D): IVector3D + { + const _local_5: number = Vector3d.dotProduct(_arg_2, _arg_4); + if(Math.abs(_local_5) < 1E-5) + { + return null; + } + const _local_6: Vector3d = Vector3d.dif(k, _arg_3); + const _local_7: number = (-(Vector3d.dotProduct(_arg_4, _local_6)) / _local_5); + const _local_8: Vector3d = Vector3d.sum(k, Vector3d.product(_arg_2, _local_7)); + return _local_8; + } + + + public get updateId(): number + { + return this._updateId; + } + + public get scale(): number + { + return this._scale / Math.sqrt(0.5); + } + + public set scale(k: number) + { + if(k <= 1) + { + k = 1; + } + k = (k * Math.sqrt(0.5)); + if(k != this._scale) + { + this._scale = k; + this._updateId++; + } + } + + public get directionAxis(): IVector3D + { + return this._directionAxis; + } + + public get location(): IVector3D + { + this._location.assign(this._loc); + this._location.x = (this._location.x * this._x_scale); + this._location.y = (this._location.y * this._y_scale); + this._location.z = (this._location.z * this._z_scale); + return this._location; + } + + public set location(k: IVector3D) + { + if(k == null) + { + return; + } + if(this._loc == null) + { + this._loc = new Vector3d(); + } + const _local_2: number = this._loc.x; + const _local_3: number = this._loc.y; + const _local_4: number = this._loc.z; + this._loc.assign(k); + this._loc.x = (this._loc.x / this._x_scale); + this._loc.y = (this._loc.y / this._y_scale); + this._loc.z = (this._loc.z / this._z_scale); + if((((!(this._loc.x == _local_2)) || (!(this._loc.y == _local_3))) || (!(this._loc.z == _local_4)))) + { + this._updateId++; + } + } + + public get direction(): IVector3D + { + return this._direction; + } + + public set direction(k: IVector3D) + { + let _local_21: number; + let _local_22: number; + let _local_23: Vector3d; + let _local_24: Vector3d; + let _local_25: Vector3d; + if(k == null) + { + return; + } + if(this._dir == null) + { + this._dir = new Vector3d(); + } + const _local_2: number = this._dir.x; + const _local_3: number = this._dir.y; + const _local_4: number = this._dir.z; + this._dir.assign(k); + this._direction.assign(k); + if((((!(this._dir.x == _local_2)) || (!(this._dir.y == _local_3))) || (!(this._dir.z == _local_4)))) + { + this._updateId++; + } + const _local_5: Vector3d = new Vector3d(0, 1, 0); + const _local_6: Vector3d = new Vector3d(0, 0, 1); + const _local_7: Vector3d = new Vector3d(1, 0, 0); + const _local_8: number = ((k.x / 180) * Math.PI); + const _local_9: number = ((k.y / 180) * Math.PI); + const _local_10: number = ((k.z / 180) * Math.PI); + const _local_11: number = Math.cos(_local_8); + const _local_12: number = Math.sin(_local_8); + const _local_13: Vector3d = Vector3d.sum(Vector3d.product(_local_5, _local_11), Vector3d.product(_local_7, -(_local_12))); + const _local_14: Vector3d = new Vector3d(_local_6.x, _local_6.y, _local_6.z); + const _local_15: Vector3d = Vector3d.sum(Vector3d.product(_local_5, _local_12), Vector3d.product(_local_7, _local_11)); + const _local_16: number = Math.cos(_local_9); + const _local_17: number = Math.sin(_local_9); + const _local_18: Vector3d = new Vector3d(_local_13.x, _local_13.y, _local_13.z); + const _local_19: Vector3d = Vector3d.sum(Vector3d.product(_local_14, _local_16), Vector3d.product(_local_15, _local_17)); + const _local_20: Vector3d = Vector3d.sum(Vector3d.product(_local_14, -(_local_17)), Vector3d.product(_local_15, _local_16)); + if(_local_10 != 0) + { + _local_21 = Math.cos(_local_10); + _local_22 = Math.sin(_local_10); + _local_23 = Vector3d.sum(Vector3d.product(_local_18, _local_21), Vector3d.product(_local_19, _local_22)); + _local_24 = Vector3d.sum(Vector3d.product(_local_18, -(_local_22)), Vector3d.product(_local_19, _local_21)); + _local_25 = new Vector3d(_local_20.x, _local_20.y, _local_20.z); + this._x.assign(_local_23); + this._y.assign(_local_24); + this._z.assign(_local_25); + this._directionAxis.assign(this._z); + } + else + { + this._x.assign(_local_18); + this._y.assign(_local_19); + this._z.assign(_local_20); + this._directionAxis.assign(this._z); + } + } + + public set x_scale(k: number) + { + if(this._x_scale != (k * this._x_scale_internal)) + { + this._x_scale = (k * this._x_scale_internal); + this._updateId++; + } + } + + public set y_scale(k: number) + { + if(this._y_scale != (k * this._y_scale_internal)) + { + this._y_scale = (k * this._y_scale_internal); + this._updateId++; + } + } + + public set z_scale(k: number) + { + if(this._z_scale != (k * this._z_scale_internal)) + { + this._z_scale = (k * this._z_scale_internal); + this._updateId++; + } + } + + public dispose(): void + { + this._x = null; + this._y = null; + this._z = null; + this._loc = null; + this._dir = null; + this._directionAxis = null; + this._location = null; + if(this._displacements != null) + { + this._displacements.clear(); + this._displacements = null; + } + } + + public setDisplacement(k: IVector3D, _arg_2: IVector3D): void + { + let _local_3: string; + let _local_4: Vector3d; + if(((k == null) || (_arg_2 == null))) + { + return; + } + if(this._displacements != null) + { + _local_3 = Math.trunc(Math.round(k.x)) + '_' + Math.trunc(Math.round(k.y)) + '_' + Math.trunc(Math.round(k.z)); + this._displacements.delete(_local_3); + _local_4 = new Vector3d(); + _local_4.assign(_arg_2); + this._displacements.set(_local_3, _local_4); + this._updateId++; + } + } + + private getDisplacenent(k: IVector3D): IVector3D + { + let _local_2: string; + if(this._displacements != null) + { + _local_2 = Math.trunc(Math.round(k.x)) + '_' + Math.trunc(Math.round(k.y)) + '_' + Math.trunc(Math.round(k.z)); + return this._displacements.get(_local_2); + } + return null; + } + + public setDepthVector(k: IVector3D): void + { + let _local_18: number; + let _local_19: number; + let _local_20: Vector3d; + let _local_21: Vector3d; + let _local_22: Vector3d; + const _local_2: Vector3d = new Vector3d(0, 1, 0); + const _local_3: Vector3d = new Vector3d(0, 0, 1); + const _local_4: Vector3d = new Vector3d(1, 0, 0); + const _local_5: number = ((k.x / 180) * Math.PI); + const _local_6: number = ((k.y / 180) * Math.PI); + const _local_7: number = ((k.z / 180) * Math.PI); + const _local_8: number = Math.cos(_local_5); + const _local_9: number = Math.sin(_local_5); + const _local_10: Vector3d = Vector3d.sum(Vector3d.product(_local_2, _local_8), Vector3d.product(_local_4, -(_local_9))); + const _local_11: Vector3d = new Vector3d(_local_3.x, _local_3.y, _local_3.z); + const _local_12: Vector3d = Vector3d.sum(Vector3d.product(_local_2, _local_9), Vector3d.product(_local_4, _local_8)); + const _local_13: number = Math.cos(_local_6); + const _local_14: number = Math.sin(_local_6); + const _local_15: Vector3d = new Vector3d(_local_10.x, _local_10.y, _local_10.z); + const _local_16: Vector3d = Vector3d.sum(Vector3d.product(_local_11, _local_13), Vector3d.product(_local_12, _local_14)); + const _local_17: Vector3d = Vector3d.sum(Vector3d.product(_local_11, -(_local_14)), Vector3d.product(_local_12, _local_13)); + if(_local_7 != 0) + { + _local_18 = Math.cos(_local_7); + _local_19 = Math.sin(_local_7); + _local_20 = Vector3d.sum(Vector3d.product(_local_15, _local_18), Vector3d.product(_local_16, _local_19)); + _local_21 = Vector3d.sum(Vector3d.product(_local_15, -(_local_19)), Vector3d.product(_local_16, _local_18)); + _local_22 = new Vector3d(_local_17.x, _local_17.y, _local_17.z); + this._depth.assign(_local_22); + } + else + { + this._depth.assign(_local_17); + } + this._updateId++; + } + + public adjustLocation(k: IVector3D, _arg_2: number): void + { + if(((k == null) || (this._z == null))) + { + return; + } + const _local_3: Vector3d = Vector3d.product(this._z, -(_arg_2)); + const _local_4: Vector3d = new Vector3d((k.x + _local_3.x), (k.y + _local_3.y), (k.z + _local_3.z)); + this.location = _local_4; + } + + public getCoordinatePosition(k: IVector3D): IVector3D + { + if(k == null) + { + return null; + } + const _local_2: number = Vector3d.scalarProjection(k, this._x); + const _local_3: number = Vector3d.scalarProjection(k, this._y); + const _local_4: number = Vector3d.scalarProjection(k, this._z); + const _local_5: Vector3d = new Vector3d(_local_2, _local_3, _local_4); + return _local_5; + } + + public getScreenPosition(k: IVector3D): IVector3D + { + let _local_2: Vector3d = Vector3d.dif(k, this._loc); + _local_2.x = (_local_2.x * this._x_scale); + _local_2.y = (_local_2.y * this._y_scale); + _local_2.z = (_local_2.z * this._z_scale); + let _local_3: number = Vector3d.scalarProjection(_local_2, this._depth); + if(((_local_3 < this._clipNear) || (_local_3 > this._clipFar))) + { + return null; + } + let _local_4: number = Vector3d.scalarProjection(_local_2, this._x); + let _local_5: number = -(Vector3d.scalarProjection(_local_2, this._y)); + _local_4 = (_local_4 * this._scale); + _local_5 = (_local_5 * this._scale); + const _local_6: IVector3D = this.getDisplacenent(k); + if(_local_6 != null) + { + _local_2 = Vector3d.dif(k, this._loc); + _local_2.add(_local_6); + _local_2.x = (_local_2.x * this._x_scale); + _local_2.y = (_local_2.y * this._y_scale); + _local_2.z = (_local_2.z * this._z_scale); + _local_3 = Vector3d.scalarProjection(_local_2, this._depth); + } + _local_2.x = _local_4; + _local_2.y = _local_5; + _local_2.z = _local_3; + return _local_2; + } + + public getScreenPoint(k: IVector3D): Point + { + const _local_2: IVector3D = this.getScreenPosition(k); + if(_local_2 == null) + { + return null; + } + const _local_3: Point = new Point(_local_2.x, _local_2.y); + return _local_3; + } + + public getPlanePosition(k: Point, _arg_2: IVector3D, _arg_3: IVector3D, _arg_4: IVector3D): Point + { + let _local_15: number; + let _local_16: number; + const _local_5: number = (k.x / this._scale); + const _local_6: number = (-(k.y) / this._scale); + const _local_7: Vector3d = Vector3d.product(this._x, _local_5); + _local_7.add(Vector3d.product(this._y, _local_6)); + const _local_8: Vector3d = new Vector3d((this._loc.x * this._x_scale), (this._loc.y * this._y_scale), (this._loc.z * this._z_scale)); + _local_8.add(_local_7); + const _local_9: IVector3D = this._z; + const _local_10: Vector3d = new Vector3d((_arg_2.x * this._x_scale), (_arg_2.y * this._y_scale), (_arg_2.z * this._z_scale)); + const _local_11: Vector3d = new Vector3d((_arg_3.x * this._x_scale), (_arg_3.y * this._y_scale), (_arg_3.z * this._z_scale)); + const _local_12: Vector3d = new Vector3d((_arg_4.x * this._x_scale), (_arg_4.y * this._y_scale), (_arg_4.z * this._z_scale)); + const _local_13: IVector3D = Vector3d.crossProduct(_local_11, _local_12); + const _local_14: Vector3d = new Vector3d(); + _local_14.assign(RoomGeometry.getIntersectionVector(_local_8, _local_9, _local_10, _local_13)); + if(_local_14 != null) + { + _local_14.subtract(_local_10); + _local_15 = ((Vector3d.scalarProjection(_local_14, _arg_3) / _local_11.length) * _arg_3.length); + _local_16 = ((Vector3d.scalarProjection(_local_14, _arg_4) / _local_12.length) * _arg_4.length); + return new Point(_local_15, _local_16); + } + return null; + } + + public performZoom(): void + { + if(this.isZoomedIn()) + { + this.scale = RoomGeometry.SCALE_ZOOMED_OUT; + } + else + { + this.scale = RoomGeometry.SCALE_ZOOMED_IN; + } + } + + public isZoomedIn(): boolean + { + return this.scale == RoomGeometry.SCALE_ZOOMED_IN; + } + + public performZoomOut(): void + { + this.scale = RoomGeometry.SCALE_ZOOMED_OUT; + } + + public performZoomIn(): void + { + this.scale = RoomGeometry.SCALE_ZOOMED_IN; + } +} \ No newline at end of file diff --git a/src/room/utils/RoomId.ts b/src/room/utils/RoomId.ts new file mode 100644 index 00000000..c14edbfe --- /dev/null +++ b/src/room/utils/RoomId.ts @@ -0,0 +1,14 @@ +export class RoomId +{ + private static PREVIEW_ROOM_ID_BASE: number = 0x7FFF0000; + + public static makeRoomPreviewerId(k: number): number + { + return (k & 0xFFFF) + RoomId.PREVIEW_ROOM_ID_BASE; + } + + public static isRoomPreviewerId(k: number): boolean + { + return (k >= RoomId.PREVIEW_ROOM_ID_BASE); + } +} \ No newline at end of file diff --git a/src/room/utils/SpriteUtilities.ts b/src/room/utils/SpriteUtilities.ts new file mode 100644 index 00000000..7513d505 --- /dev/null +++ b/src/room/utils/SpriteUtilities.ts @@ -0,0 +1,16 @@ +import { BLEND_MODES } from 'pixi.js'; + +export class SpriteUtilities +{ + public static hex2int(hex: string): number + { + return parseInt(hex, 16); + } + + public static inkToBlendMode(ink: string | number): number + { + if(ink == 'ADD' || ink == 33) return BLEND_MODES.ADD; + + return BLEND_MODES.NORMAL; + } +} \ No newline at end of file diff --git a/src/room/utils/TextureUtils.ts b/src/room/utils/TextureUtils.ts new file mode 100644 index 00000000..08c1f940 --- /dev/null +++ b/src/room/utils/TextureUtils.ts @@ -0,0 +1,47 @@ +import { DisplayObject, Rectangle, Renderer, RenderTexture, SCALE_MODES, Texture } from 'pixi.js'; +import { Nitro } from '../../nitro/Nitro'; + +export class TextureUtils +{ + private static _renderer: Renderer = null; + + public static generateTexture(displayObject: DisplayObject, region: Rectangle = null, scaleMode: number = SCALE_MODES.NEAREST, resolution: number = 1): RenderTexture + { + if(!displayObject) return null; + + return TextureUtils.getRenderer().generateTexture(displayObject, scaleMode, resolution, region); + } + + public static generateTextureFromImage(image: HTMLImageElement): Texture + { + if(!image) return null; + + return Texture.from(image); + } + + public static generateImage(target: DisplayObject | RenderTexture): HTMLImageElement + { + if(!target) return null; + + return TextureUtils.getRenderer().extract.image(target); + } + + public static generateImageUrl(target: DisplayObject | RenderTexture): string + { + if(!target) return null; + + return TextureUtils.getRenderer().extract.base64(target); + } + + public static getRenderer(): Renderer + { + if(!TextureUtils._renderer) return Nitro.instance.renderer; + + return TextureUtils._renderer; + } + + public static setRenderer(renderer: Renderer): void + { + TextureUtils._renderer = renderer; + } +} diff --git a/src/room/utils/Vector3d.ts b/src/room/utils/Vector3d.ts new file mode 100644 index 00000000..ee46c94a --- /dev/null +++ b/src/room/utils/Vector3d.ts @@ -0,0 +1,187 @@ +import { IVector3D } from './IVector3D'; + +export class Vector3d implements IVector3D +{ + private _x: number; + private _y: number; + private _z: number; + private _length: number; + + constructor(x: number = 0, y: number = 0, z: number = 0) + { + this._x = x; + this._y = y; + this._z = z; + this._length = NaN; + } + + public static sum(vector1: IVector3D, vector2: IVector3D): Vector3d + { + if(!vector1 || !vector2) return null; + + return new Vector3d((vector1.x + vector2.x), (vector1.y + vector2.y), (vector1.z + vector2.z)); + } + + public static dif(vector1: IVector3D, vector2: IVector3D): Vector3d + { + if(!vector1 || !vector2) return null; + + return new Vector3d((vector1.x - vector2.x), (vector1.y - vector2.y), (vector1.z - vector2.z)); + } + + public static product(vector: IVector3D, value: number): Vector3d + { + if(!vector) return null; + + return new Vector3d((vector.x * value), (vector.y * value), (vector.z * value)); + } + + public static dotProduct(vector1: IVector3D, vector2: IVector3D): number + { + if(!vector1 || !vector2) return 0; + + return (vector1.x * vector2.x) + (vector1.y * vector2.y) + (vector1.z * vector2.z); + } + + public static crossProduct(vector1: IVector3D, vector2: IVector3D): Vector3d + { + if(!vector1 || !vector2) return null; + + return new Vector3d(((vector1.y * vector2.z) - (vector1.z * vector2.y)), ((vector1.z * vector2.x) - (vector1.x * vector2.z)), ((vector1.x * vector2.y) - (vector1.y * vector2.x))); + } + + public static scalarProjection(vector1: IVector3D, vector2: IVector3D): number + { + if(!vector1 || !vector2) return -1; + + const length = vector2.length; + + if(length > 0) + { + return ((vector1.x * vector2.x) + (vector1.y * vector2.y) + (vector1.z * vector2.z)) / length; + } + + return -1; + } + + public static cosAngle(vector1: IVector3D, vector2:IVector3D): number + { + if(!vector1 || !vector2) return 0; + + const totalLength = (vector1.length * vector2.length); + + if(!totalLength) return 0; + + return (Vector3d.dotProduct(vector1, vector2) / totalLength); + } + + public static isEqual(vector1: IVector3D, vector2: IVector3D): boolean + { + if(!vector1 || !vector2) return false; + + if((vector1.x !== vector2.x) || (vector1.y !== vector2.y) || (vector1.z !== vector2.z)) return false; + + return true; + } + + public negate(): void + { + this._x = -(this._x); + this._y = -(this._y); + this._z = -(this._z); + } + + public add(vector: IVector3D): void + { + if(!vector) return; + + this._x += vector.x; + this._y += vector.y; + this._z += vector.z; + this._length = NaN; + } + + public subtract(vector: IVector3D): void + { + if(!vector) return; + + this._x -= vector.x; + this._y -= vector.y; + this._z -= vector.z; + this._length = NaN; + } + + public multiply(amount: number): void + { + this._x *= amount; + this._y *= amount; + this._z *= amount; + this._length = NaN; + } + + public divide(amount: number): void + { + this._x /= amount; + this._y /= amount; + this._z /= amount; + this._length = NaN; + } + + public assign(vector: IVector3D): void + { + if(!vector) return; + + this._x = vector.x; + this._y = vector.y; + this._z = vector.z; + this._length = NaN; + } + + public get x(): number + { + return this._x; + } + + public set x(k: number) + { + this._x = k; + this._length = NaN; + } + + public get y(): number + { + return this._y; + } + + public set y(k: number) + { + this._y = k; + this._length = NaN; + } + + public get z(): number + { + return this._z; + } + + public set z(k: number) + { + this._z = k; + this._length = NaN; + } + + public get length(): number + { + if(isNaN(this._length)) + { + this._length = Math.sqrt(((this._x * this._x) + (this._y * this._y)) + (this._z * this._z)); + } + + return this._length; + } + + public toString(): string + { + return `[Vector3d: ${ this._x }, ${ this._y }, ${ this._z }]`; + } +} \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000..71ddb774 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compileOnSave": false, + "compilerOptions": { + "baseUrl": "./src", + "outDir": "./dist", + "sourceMap": false, + "declaration": true, + "experimentalDecorators": true, + "moduleResolution": "node", + "importHelpers": true, + "resolveJsonModule": true, + "allowSyntheticDefaultImports": true, + "target": "es2015", + "module": "es6", + "lib": [ + "es2018", + "dom" + ] + } +}